小编典典

熊猫to_sql截断我的数据

sql

df.to_sql(con=con_mysql, name='testdata', if_exists='replace', flavor='mysql')用来将数据框导出到mysql中。但是,我发现具有长字符串内容(例如url)的列被截断为63位数字。导出时,我从ipython笔记本收到以下警告:

/usr/local/lib/python2.7/site-
packages/pandas/io/sql.py:248:警告:第3行cur.executemany(insert_query,data)的列’url’的数据被截断了

对于不同的行,还存在其他相同样式的警告。

有什么我可以调整的方法来正确导出完整数据吗?我可以在mysql中设置正确的数据架构,然后导出到该数据库。但是我希望进行调整可以使其直接从python运行。


阅读 225

收藏
2021-04-19

共1个答案

小编典典

如果您使用的是熊猫 0.13.1或更早版本
,则由于代码中的这一行,确实对63位的限制进行了硬编码:https
//github.com/pydata/pandas/blob/v0.13.1/pandas/io/
sql.py#L278

作为一种解决方法,您可能可以monkeypatch该功能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,并将字符串转换为sqlalchemyTEXT类型,其中wich转换为mysqlTEXT类型(而不是VARCHAR),这也将允许您存储大于63位数字的较大字符串:

engine = sqlalchemy.create_engine('mysql://scott:tiger@localhost/foo')
df.to_sql('testdata', engine, if_exists='replace')

仅当您仍然使用DBAPI连接而不是sqlalchemy引擎时,问题仍然存在,但是不建议使用此选项,建议向提供一个sqlalchemy引擎to_sql

2021-04-19