编程界的小学生一枚,主要使用语言为python,平时要和数据打交道,还有erp系统相关以及web开发等等,有时间就会分享下工作中遇到的那点事,包括那些让我焦虑的问题,包括我自己总结的小技巧,那些程序优化重构的实现,还有可能包括程序性能优化,以及源码的阅读等等···在荆棘的道路上逆风前行
本文基于python, pandas, pymysql实现了向数据库中批量插入数据的脚本,一方面提供给被网上很多瞎转载的答案给坑蒙了的人(因为我也是),一方面自己也做个笔记,以后方便查阅
最近在处理一个需求,有关批量往数据库插入数据的,描述如下
这个脚本是基于linux系统写的
三方库 pandas 1.0.5, pymysql 0.9.3
python版本 3.7
标准库 os
实际上,最后一步,要写入数据库的文件数据是存储在内存中的。因为读取文件后进行的计算都是在内存中进行的,那么计算的结果也没必要再写到本地,再去读取,再写入数据库,这是会影响程序的效率的
给文件路径,然后去读文件就行了,强调一下需要注意的点
import pandas as pd
import numpy as np
# 当前脚本的位置
current_folder_path = os.path.dirname(__file__)
# 你的文件的位置
your_file_path1 = os.path.join(current_folder_path, "文件的名字1")
your_file_path2 = os.path.join(current_folder_path, "文件的名字2")
# 我这里是以读取csv文件为例, delimiter为我们内部约定的列之间的分割符
df1 = pd.read_csv(your_file_path1, dtype={"column1": str, "column2": str}, delimiter="/t")
df2 = pd.read_csv(your_file_path2, dtype={"column1": str, "column2": str}, delimiter="/t")
文件的拼接主要就是merge和concat两个语法的使用,强调一下小知识点
# 这里以左连接举例, 假设只有两个文件拼接
ret_df = pd.merge(df1, df2, left_on=["column_name"], right_on=["column_name"], how="left")
导入三方库pymysql,初始化连接
# pymysql的接口获取链接
def mysql_conn(host, user, password, db, port=3306, charset="utf8"):
# 传参版本
conn = pymysql.connect(host=host, user=user, password=password, database=db, port=port, charset=charset)
return conn
# 先创建cursor负责操作conn接口
conn = mysql_conn("your db host", "your username", "your password", "db name")
cursor = conn.cursor()
# 开启事务
conn.begin()
############# 构造批量数据的过程 #############
# 先构造需要的或是和数据库相匹配的列
columns = list(df.columns)
# 可以删除不要的列或者数据库没有的列名
columns.remove("列名")
# 重新构造df,用上面的columns,到这里你要保证你所有列都要准备往数据库写入了
new_df = df[columns].copy()
# 构造符合sql语句的列,因为sql语句是带有逗号分隔的,(这个对应上面的sql语句的(column1, column2, column3))
columns = ','.join(list(new_df.columns))
# 构造每个列对应的数据,对应于上面的((value1, value2, value3))
data_list = [tuple(i) for i in gdsord_df.values] # 每个元组都是一条数据,根据df行数生成多少元组数据
# 计算一行有多少value值需要用字符串占位
s_count = len(data_list[0]) * "%s,"
# 构造sql语句
insert_sql = "insert into " + "数据库表名" + " (" + columns + ") values (" + s_count[:-1] + ")"
这个简单,直接上代码
cursor.executemany(insert_sql, data_list)
conn.commit()
cursor.close()
conn.close()
如果没问题的话,就可以同时进行多个文件读取,启用多线程同时向数据库中写入数据了,非常高效!
import pandas as pd
import numpy as np
# pymysql接口
def mysql_conn(host, user, password, db, port=3306, charset="utf8"):
conn = pymysql.connect(host=host, user=user, password=password, database=db, port=port, charset=charset)
return conn
# 当前脚本的位置
current_folder_path = os.path.dirname(__file__)
# 你的文件的位置
your_file_path1 = os.path.join(current_folder_path, "文件的名字1")
your_file_path2 = os.path.join(current_folder_path, "文件的名字2")
# 我这里是以读取csv文件为例, delimiter为我们内部约定的列之间的分割符
df1 = pd.read_csv(your_file_path1, dtype={"column1": str, "column2": str}, delimiter="/t")
df2 = pd.read_csv(your_file_path2, dtype={"column1": str, "column2": str}, delimiter="/t")
# 合并
ret_df = pd.merge(df1, df2, left_on=["column_name"], right_on=["column_name"], how="left")
# 先创建cursor负责操作conn接口
conn = mysql_conn("your db host", "your username", "your password", "db name")
cursor = conn.cursor()
# 开启事务
conn.begin()
# 先构造需要的或是和数据库相匹配的列
columns = list(df.columns)
# 可以删除不要的列或者数据库没有的列名
columns.remove("列名")
# 重新构造df,用上面的columns,到这里你要保证你所有列都要准备往数据库写入了
new_df = df[columns].copy()
# 构造符合sql语句的列,因为sql语句是带有逗号分隔的,(这个对应上面的sql语句的(column1, column2, column3))
columns = ','.join(list(new_df.columns))
# 构造每个列对应的数据,对应于上面的((value1, value2, value3))
data_list = [tuple(i) for i in gdsord_df.values] # 每个元组都是一条数据,根据df行数生成多少元组数据
# 计算一行有多少value值需要用字符串占位
s_count = len(data_list[0]) * "%s,"
# 构造sql语句
insert_sql = "insert into " + "数据库表名" + " (" + columns + ") values (" + s_count[:-1] + ")"
try:
cursor.executemany(insert_sql, data_list)
conn.commit()
cursor.close()
conn.close()
except Exception as e:
# 万一失败了,要进行回滚操作
conn.rollback()
cursor.close()
conn.close()