微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

python – pandas to_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: Warning: Data truncated for column ‘url’ at row 3
cur.executemany(insert_query, data)

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

有什么我可以调整以正确导出完整数据吗?我可以在MysqL中设置正确的数据模式,然后导出到该模式.但是我希望调整可以让它直接从python中运行.

解决方法:

如果您使用的是0.13.1或更早的pandas,这个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,字符串转换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引擎.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐