Python3 加xlrd实现xls文件插入mysql

0x00序言

老师给的项目,其中一个小的模块,需要上传xls文件并将其数据插入数据库。

0x01重点及弯路

1、编码问题

老师提供的xls中有一些字符并不符合标准,所以有时候插入会报错。例如比较典型的就是他其中有一个字无法识别导致的错误,这个bug其实没有任何技术含量,但是它却让我尝试了很久。

2、mysql的规定

建表之时就出现的问题,mysql中表的字段名称不能包含-这个符号,而老师提供的xls文件中偏偏有一个字段中带有-符号。两种解决方法。更改xls文件,和甲方说明原因,如果可以更改最好。或者在程序内处理,即读出xls文件后单个去除,不过这种效率不高,很容易造成新的bug,而且普适性不强。

3、特殊问题

读xls文件中某一个字段时,明明是空的,但是却读出了\n\n\n这样的三个回车符,而且没有带转义,如果直接操作,在python中可能会出错。因为我个人对xls没有研究,只是利用xlrd实现一个小模块,所以我也只能针对于这个问题单独处理,但是这样却可能产生新的bug。

4、调试

调试过程中,如果程序已经调试到mysql执行语句的时候仍然没有出错,但是在执行时却出错了,就一定要小心了,因为pymysql和mysql执行的时候其实有一些细小的区别,虽然大部分情况可以忽略不记,但是在调试的时候确是一个关键点。

0x02实现


import os
import xlrd
import pymysql
from datetime import datetime
from xlrd import xldate_as_tuple


def list_deal(list):  # 处理非正常读出的数据,例如在管理员备注中的,读出是空格,但是却出现了\n\n\n这个字符串
    i = 0
    while i < len(list):
        if list[i] == "\n\n\n":
            list[i] = ""
        i = i + 1
    new_list = [str(x) for x in list]
    return new_list


def list2valuestr(list):  # 转化读出的列表为table中的属性字段
    new_list = list_deal(list)
    new_str = "'" + "','".join(new_list) + "'"
    return new_str


def list2attributestr(list):  # 转化读出的列表为值字段
    new_string = ", ".join(list)
    return new_string


def xls2mysql(file_name, db, cur): # xls文件插入mysql数据库
    pass


def SQL(): # 获取数据库操作重要字段
    db = pymysql.connect("localhost", "fsm", "123456", "cas", use_unicode=True, charset="utf8")
    cur = db.cursor()
    return db, cur


def file_inspection(file_name):  # 文件检验,防止0day攻击
    file_list = os.path.splitext(file_name)
    if file_list and not os.path.splitext(file_list[0])[1]:
        if os.path.exists(file_name):
            print("file_already_exists!!!")
        elif file_list[1] == ".xls":
            update_database(file_name)


def update_database(file_name):  # 读取xls,并将数据插入到mysql数据库中
    db, cur = SQL()
    data = xlrd.open_workbook(file_name)
    # print('所有sheet名称', data.sheet_names())
    sheet1 = data.sheet_by_name("订单")  # 通过sheet的名称进行查找
    attribute_value = sheet1.row_values(0)  # 第一行代表数据库中所有的属性
    # print(sheet1.row_values(2))
    i = 1
    while i< sheet1.nrows:
        try:
            realvalue = sheet1.row_values(i)
            insert_string = "insert into cas({}) values({});".format(list2attributestr(attribute_value), list2valuestr(realvalue))
            cur.execute(insert_string)
            i = i + 1
        except:
            i = i + 1
            pass
    cur.close()
    db.commit()
    db.close()
update_database("./test.xls")

代码并非最终版本,许多差错处理仍然没有写入,不过实际插入是可行的。

一定要注意,有些xls文件中的某一个框中可能带有单个单引号影响你的插入,这个时候可以转化为原生字符串来解决。

你可能感兴趣的:(Mysql,python,Python,Mysql)