Pandas - write_frame 到 sqlite - datetime64[ns]

Row*_*ney 3 python sqlite postgresql pandas

我正在尝试从 postgresql 数据库查询数据并将其插入到 sqlite 数据库中。

这是我的代码:

import pandas as pd
import pandas.io.sql as pd_sql
import sqlite3 as sql3
import psycopg2

#Aquire Data FROM PostgreSQL DB
conn_pg = psycopg2.connect("dbname='xx' user='xxxxx' host=xxx.xxx.xx.xxx password='xxxx'");
sql_1='SELECT * FROM table1 limit 5'
df_1=pd_sql.read_frame(sql_1,conn_pg)
conn_pg.close()

#Insert Into sqlite3 DB
conn_sqlite=sql3.connect('/xxxx/xxxx/xxxx/xxxx/my_db.db')
pd_sql.write_frame(df_1,'table1',conn_sqlite,'sqlite',if_exists='replace')
conn_sqlite.close()
Run Code Online (Sandbox Code Playgroud)

df_1 具有 dtypes:
field1 对象
field2 datetime64[ns]
field3 float64
field4 对象
dtype:对象

我收到错误:

InterfaceError: Error binding parameter 1 - probably unsupported type.  
Run Code Online (Sandbox Code Playgroud)

在:

pd_sql.write_frame(df_1,'table1',conn_sqlite,'sqlite',if_exists='replace')
Run Code Online (Sandbox Code Playgroud)

我猜 sqlite 不喜欢 field2 的 datetime64 。我需要帮助来弄清楚:
1. 我应该在数据框中将 field2 转换为哪种日期类型
2. 如何在 pandas DataFrame 中执行此操作

任何帮助将非常感激。
干杯!

jor*_*ris 5

您确实是正确的,datetime64 字段造成了麻烦。Sqlite 没有真正的日期时间类型,但它们使用文本或整数类型来表示时间(请参阅http://www.sqlite.org/datatype3.htmlhttp://www.sqlite.org/lang_datefunc.html)。

因此,根据您想要执行的操作,您可以首先将日期时间列转换为字符串:

df['field2'] = df['field2'].apply(str)
Run Code Online (Sandbox Code Playgroud)

或 int (自 1970-01-01 00:00:00 UTC 以来的秒数):

df['field2'] = df['field2'].astype('int64')
Run Code Online (Sandbox Code Playgroud)

然后将数据写入sqlite。


旁注:

  • 您使用什么版本的熊猫?因为在0.13版本(或更低版本)的实现中存在一个错误if_exists='replace',该错误在0.13.1(目前最新的稳定版本)中修复
  • 在即将发布的 pandas 0.14 中,将有一个基于 sqlalchemy 的 sql 函数的新实现,并且将自动转换为字符串(因此 datetime64 数据不再出错)。