我有一个如下所示的数据框:
df = pd.DataFrame(index= pd.date_range('2014-01-01', periods=10))
df['date'] = df.index.map(lambda x: x.strftime('%d-%m-%Y'))
df['date'] = df.index
df['profit']= rand(10)
df['perf_period_id']=2
还有一个带有名为fee_profit
的表的sqlite3数据库fee_profit有4个字段:
当我尝试使用(不显示数据库连接)将数据帧写入数据库时:
df.to_sql(name='fee_profit', index=False, con=db, if_exists='append')
我得到以下代码:
252 else:
253 data = [tuple(x) for x in frame.values.tolist()]
--> 254 cur.executemany(insert_query, data)
255
256
InterfaceError: Error binding parameter 0 - probably unsupported type.
没有传递主键(这可能是问题吗?)我把桌子弄乱了,看起来肯定是日期问题。尝试了在索引中传递日期的各种组合,也是字符串,没有任何作用。
知道我哪里出错了。无法在任何地方找到使用此方法的示例。
使用Pandas 0.13.1和sqlite 3 2.6.0。数据库是通过django 1.6模型创建的
答案 0 :(得分:3)
更新:从pandas 0.15开始,to_sql
支持将两个sqlite连接的日期时间值写为sqlalchemy引擎。因此,不再需要下面描述的解决方法
Pandas 0.15将于今年10月发布,该功能将在开发版本中合并。
上述错误的原因是df
'date'列是datetime64
列,sqlite3不支持此类型。所以你应该首先将它转换为字符串(这不是为sqlite自动完成可能是错误/缺失的功能),或者转换为datetime.date
对象(由sqlite3识别,但它也将被转换为一个字符串,因为sqlite没有日期时间类型)。
您在代码示例中使用df['date'] = df.index.map(lambda x: x.strftime('%d-%m-%Y'))
执行了此操作,但随后又使用df['date'] = df.index
覆盖了该列,因此可能是您的代码示例中的错误。但是如果你先把它转换成字符串,那就可以了:
df = pd.DataFrame(index= pd.date_range('2014-01-01', periods=10))
df['date'] = df.index.map(lambda x: x.strftime('%d-%m-%Y'))
df['profit']= rand(10)
df['perf_period_id']=2
df.to_sql(name='fee_profit', index=False, con=db, if_exists='append')
从pandas 0.14开始,主要的sql函数被重构为使用sqlalchemy来处理不同的数据库风格。如果使用它,它将与datetime列一起正常工作(它会自动将其转换为字符串):
df = pd.DataFrame(index= pd.date_range('2014-01-01', periods=10))
df['profit']= rand(10)
df['perf_period_id']=2
import sqlalchemy
db2 = sqlalchemy.create_engine('...')
df.to_sql(name='fee_profit', index=False, con=db2, if_exists='append')
将来仍然会支持使用普通的sqlite连接对象而不是sqlalchemy引擎(但仅适用于sqlite!)。