背景
軟件版本:python3.7
pyhton IDE Pycharm。
需求說明:
每天有人給我微信發excel表格,然后我需要上傳到數據庫。
發送的excel表格,名稱有規律,都是名稱+日期格式。
比如:“測試_2020-01-01.xlsx”,“測試_2020-01-02.xlsx”。
有時會出現一些問題:
excel的文件格式:主要分為csv、xls、xlsx。
excel的字段和數據庫字段不一致:主要是字段數不一致,字段名稱不一致(代表的含義可能一致)
excel中的一些行數據是不需要的。
一、數據庫配置
# encoding:utf-8 import pymysql.cursors class MysqlOperation(object): def __init__(self, config): self.connection = pymysql.connect(host=config['mysql_host'], port=config['mysql_port'], user=config['mysql_user'], # pymysql直接連接是passwd,用連接池連接是password passwd=config['mysql_passwd'], db=config['mysql_db'], charset='utf8', cursorclass=pymysql.cursors.DictCursor ) def read_sql(self, sql): with self.connection.cursor() as cursor: try: cursor.execute(sql) result = cursor.fetchall() return result except Exception as e: self.connection.rollback() # 回滾 print('事務失敗', e) def insert_sql(self, sql): with self.connection.cursor() as cursor: try: cursor.execute(sql) self.connection.commit() except Exception as e: self.connection.rollback() print('事務失敗', e) def update_sql(self, sql): # sql_update ="update user set username = '%s' where id = %d" with self.connection.cursor() as cursor: try: cursor.execute(sql) # 像sql語句傳遞參數 # 提交 self.connection.commit() except Exception as e: # 錯誤回滾 self.connection.rollback() def delect_sql(self, sql_delete): with self.connection.cursor() as cursor: try: cursor.execute(sql_delete) # 像sql語句傳遞參數 # 提交 self.connection.commit() except Exception as e: # 錯誤回滾 self.connection.rollback() def read_one(self, sql): with self.connection.cursor() as cursor: try: cursor.execute(sql) result = cursor.fetchone() return result except Exception as e: self.connection.rollback() # 回滾 print('事務失敗', e) def reConnect(self): try: self.connection.ping() except: self.connection()
二、excel,mysql,python字段說明
最上面的表格未原始表格,在幾種不同情況下,字段的變化是不同的。
三、解決問題
3.1 讀取不同格式的excel
import pandas as pd file_path_csv = r'C:\Users\1\Desktop\博客\測試.csv' df_csv = pd.read_csv(file_path_csv, encoding='gbk') file_path_xls = r'C:\Users\1\Desktop\博客\測試.xls' df_xls = pd.read_excel(file_path_xls) file_path_xlsx = r'C:\Users\1\Desktop\博客\測試.xlsx' df_xlsx = pd.read_excel(file_path_xlsx)
說明:默認encoding = 'utf-8'。注意讀取csv格式時的enconding。
3.2 字段問題
3.2.1 字段數不一致
解決的方法是重新索引,使用reindex。
reindex對於已有的字段,對應的值不變。對於沒有的字段則為nan。
3.2.2 重命名字段
有些字段雖然名字不一樣,但是代表的含義是一樣的。比如excel字段“姓名”對應數據庫字段“name”。
使用rename可以解決。
import pandas as pd file_path_xlsx = r'C:\Users\1\Desktop\博客\測試.xlsx' df = pd.read_excel(file_path_xlsx) df.rename(columns={'姓名':'name'}, inplace=True)
此時便完成了對“姓名”重命名為“name”,其他不變。
3.3 對行進行篩選
具體的可以看一下我的這篇博客:https://www.cnblogs.com/qianslup/p/11898665.html 中的篩選數據
四、代碼展示
import xlwt import xlrd import os import numpy as np from sqlConnect import MysqlOperation import pymysql import pandas as pd import math import datetime # 配置數據庫 config = {'mysql_host': 'xxx', 'mysql_port': 0000, 'mysql_user': 'xxx', 'mysql_passwd': 'xxx', 'mysql_db': 'xxx' } mysql = MysqlOperation(config=config) def read_excel(path_file): df = pd.read_excel(path_file, sheet_name='Sheet1') columns_1 = [column for column in df] columns = [str(column).replace('.', '') for column in df] # 將字段在python中的“.1”轉化為mysql中的“1”且字符串化 columns_dict = dict(zip(columns_1, columns)) df.rename(columns=columns_dict, inplace=True) # 重命名字符串字段 df.dropna(how='all') df.fillna('Null', inplace=True) # 填入“null"是為了與下面的sql_insert對應。 names = ['姓名', '姓名1', 'ID', 'ID1', '年齡', '年齡1'] # 數據庫中的字段 i = 0 for name in names: if name in columns: # 判斷數據庫中的字段是否全部存在,防止將一整個字段填入NULL值 pass else: i += 1 if i == 0: df = df.reindex(columns=names) trs = [] for td in df.iloc[:].values: trs.append(f"{tuple(td)}") return trs else: print('字段不相符') def insert_mysql(path, path_file_judge): mysql.reConnect() mysql.delect_sql('delete from teble.ceshi') print('刪除完成') lists = os.listdir(path) for file in lists: # 為了循環插入 path_file = path + '\\' + file if path_file == path_file_judge: print(path_file) sql_insert = 'insert into qsl.user_evaluation(`姓名`, `姓名1`, `ID`, `ID1`, `年齡`, `年齡1`)' values = read_excel(path_file) sql_insert = sql_insert + ' values ' + ','.join(values) sql_insert = sql_insert.replace("'Null'", "Null") # read_excel中插入Null的原因 # print(sql_insert) mysql.insert_sql(sql_insert) print('插入完成') if __name__ == '__main__': path = r'D\ceshi' everyday = datetime.datetime.now() - datetime.timedelta(days=1) everyday = everyday.strftime('%Y{Y}%m{m}%d{d}').format(Y='-', m='-', d='') path_file_judge = path + '\\' + '測試_{everyday}.xlsx'.format(everyday=everyday) insert_mysql(path, path_file_judge)
這段代碼的前提是excel的字段永不變化並且和數據庫能保持一致。