Pandas之to_sql()插入数据到mysql中所遇到的问题及解决
作者:肖永威
这篇文章主要介绍了Pandas之to_sql()插入数据到mysql中所遇到的问题及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
to_sql()插入数据到mysql中所遇到的问题
使用pymysql驱动API,出现如下错误:
DatabaseError: Execution failed on sql ‘SELECT name FROM sqlite_master WHERE type=‘table’ AND name=?;’: not all arguments converted during string formatting
1. pandas的数据表插入数据到mysql中所遇到的问题
1.1. pymysql驱动接口问题
根据以往经验,mysql操作很简单,安装pymysql驱动即可。
pip install pymysql
编写了通过pandas的to_sql写入数据库的代码。
import pandas as pd import datetime import uuid # 数据库主键唯一 import pymysql def mysql_db(): # 连接数据库肯定需要一些参数 conn = pymysql.connect( host="192.168.**.**", port=3306, database="M*****DB", charset="utf8", user="ty", passwd="****" ) return conn # df = 略去 # 增加唯一主键uuid id = [] for i in range(len(df)): id.append(uuid.uuid1()) # 增加记录写入时间 df['CreateTime'] = datetime.datetime.now() df['id'] = id # 下面是出现问题的地方 conn = mysql_db() tablename = '******' dd = df[colsname] # 浮点型截断数据处理 for k,v in cols_len.items(): dd[k] = dd[k].round(v) # 下面是出现问题的地方 dd.to_sql(tablename, conn,index=False, if_exists='append')
执行程序,报出如下问题:
DatabaseError: Execution failed on sql ‘SELECT name FROM sqlite_master WHERE type=‘table’ AND name=?;’: not all arguments converted during string formatting
尝试执行查询语句:
df0=pd.read_sql('select * from S*******y',conn) df0
一切很正常,结果如下:
1.2. 关于数据库主键
主键一般使用uuid,python中的uuid模块基于信息如MAC地址、时间戳、命名空间、随机数、伪随机数来uuid。
具体方法有如下几个:
uuid.uuid1()
:基于MAC地址,时间戳,随机数来生成唯一的uuid,可以保证全球范围内的唯一性。uuid.uuid2()
:算法与uuid1相同,不同的是把时间戳的前4位置换为POSIX的UID。不过需要注意的是python中没有基于DCE的算法,所以python的uuid模块中没有uuid2这个方法。uuid.uuid3(namespace,name)
:通过计算一个命名空间和名字的md5散列值来给出一个uuid,所以可以保证命名空间中的不同名字具有不同的uuid,但是相同的名字就是相同的uuid了。其中,namespace并不是一个自己手动指定的字符串或其他量,而是在uuid模块中本身给出的一些值。比如uuid.NAMESPACE_DNS,uuid.NAMESPACE_OID,uuid.NAMESPACE_OID这些值。这些值本身也是UUID对象,根据一定的规则计算得出。uuid.uuid4()
:通过伪随机数得到uuid,是有一定概率重复的uuid.uuid5(namespace,name)
:和uuid3基本相同,只不过采用的散列算法是sha1。
使用时,按数据集中的记录数,一次性生成uuid列表,并入到表中。
2. pandas的to_sql()有个隐藏的坑
解决办法
查了pandas官网和其他不少有关to_sql的文章,都没有看到有提及数据库连接这个坑,不过在pandas官网的to_sql例子和其他文章的to_sql中都有一个共同点,就是引用sqlalchemy这个第三方ORM库来进行连接的,据此解决to_sql这个报错。
首先,安装 sqlalchemy。
pip install sqlalchemy
修改代码,增加函数:
def mysql_engine_db(): # 连接数据库肯定需要一些参数 engine = create_engine( 'mysql+pymysql://ty:***@192.168.**.**:3306/M*******DB' # mysql+pymysql://用户: 密码@url: 端口/数据库 ) return engine # 下面是出现问题的地方 engine= mysql_engine_db() tablename = '******' dd = df[colsname] # 浮点型截断数据处理 for k,v in cols_len.items(): dd[k] = dd[k].round(v) # 下面是出现问题的地方 dd.to_sql(tablename, engine,index=False, if_exists='append')
如此简单的解决问题!
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。