如果您使用的是 pandas 0.13.1 或更早版本,这个 63 位数字的限制确实是硬编码的,因为代码中有这行:https://github.com/pydata/pandas/blob/v0.13.1/pandas/io/sql.py#L278
作为一种变通方法,您也许可以对该函数 get_sqltype 进行猴子补丁:
from pandas.io import sql
def get_sqltype(pytype, flavor):
sqltype = {'mysql': 'VARCHAR (63)', # <-- change this value to something sufficient higher
'sqlite': 'TEXT'}
if issubclass(pytype, np.floating):
sqltype['mysql'] = 'FLOAT'
sqltype['sqlite'] = 'REAL'
if issubclass(pytype, np.integer):
sqltype['mysql'] = 'BIGINT'
sqltype['sqlite'] = 'INTEGER'
if issubclass(pytype, np.datetime64) or pytype is datetime:
sqltype['mysql'] = 'DATETIME'
sqltype['sqlite'] = 'TIMESTAMP'
if pytype is datetime.date:
sqltype['mysql'] = 'DATE'
sqltype['sqlite'] = 'TIMESTAMP'
if issubclass(pytype, np.bool_):
sqltype['sqlite'] = 'INTEGER'
return sqltype[flavor]
sql.get_sqltype = get_sqltype
然后只需使用您的代码即可:
df.to_sql(con=con_mysql, name='testdata', if_exists='replace', flavor='mysql')
从 pandas 0.14 开始,sql 模块在底层使用 sqlalchemy,字符串转换为 sqlalchemy TEXT 类型,然后转换为 mysql TEXT 类型(而不是VARCHAR),这也将允许您存储大于 63 位的字符串:
engine = sqlalchemy.create_engine('mysql://scott:tiger@localhost/foo')
df.to_sql('testdata', engine, if_exists='replace')
仅当您仍然使用 DBAPI 连接而不是 sqlalchemy 引擎时,问题仍然存在,但此选项已弃用,建议向 to_sql 提供 sqlalchemy 引擎。