pandas to_sql截断my d

2024-05-14 07:49:49 发布

您现在位置:Python中文网/ 问答频道 /正文

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

/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中运行。在


Tags: to数据nameurl警告dfsqlif
2条回答

如果您使用的是pandas0.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

然后只要使用你的代码就可以了:

^{pr2}$

从pandas0.14开始,sql模块在幕后使用sqlalchemy,字符串被转换为sqlalchemyTEXT类型,并转换为mysqlTEXT类型(而不是VARCHAR),这也允许您存储大于63位数的字符串:

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

只有当您仍然使用DBAPI连接而不是sqlalchemy引擎时,问题仍然存在,但是不推荐使用此选项,建议为to_sql提供sqlalchemy引擎。在

受到@joris答案的启发,我决定将更改硬编码到panda的源代码中并重新编译。在

cd /usr/local/lib/python2.7/dist-packages/pandas-0.14.1-py2.7-linux-x86_64.egg/pandas/io
sudo pico sql.py

更改行871

^{pr2}$

'mysql': 'VARCHAR (255)',

然后重新编译这个文件

sudo python -m py_compile sql.py

重新启动脚本,_to_sql()函数编写了一个表。 (我原以为重新编译会破坏熊猫,但似乎没有。)

下面是我写一个mysql数据帧的脚本,供参考。在

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import sqlalchemy 
from sqlalchemy import create_engine
df = pd.read_csv('10k.csv')
## ... dataframe munging
df = df.where(pd.notnull(df), None) # workaround for NaN bug
engine = create_engine('mysql://user:password@localhost:3306/dbname')
con = engine.connect().connection
df.to_sql("issues", con, 'mysql', if_exists='replace', index=True, index_label=None)

相关问题 更多 >

    热门问题