如何使用 pandas sqlalchemy 和 psycopg2 处理 NaT
Posted
技术标签:
【中文标题】如何使用 pandas sqlalchemy 和 psycopg2 处理 NaT【英文标题】:How to handle NaTs with pandas sqlalchemy and psycopg2 【发布时间】:2017-05-04 18:31:50 【问题描述】:我有一个带有类似 NaT 的数据框,这给了我一个 DataError: (psycopg2.DataError) invalid input syntax for type timestamp: "NaT"
:当我尝试将值插入到 postgres db 中时
数据框
from sqlalchemy import MetaData
from sqlalchemy.dialects.postgresql import insert
import pandas as pd
tst_df = pd.DataFrame('colA':['a','b','c','a','z', 'q'],
'colB': pd.date_range(end=datetime.datetime.now() , periods=6),
'colC' : ['a1','b2','c3','a4','z5', 'q6'])
tst_df.loc[5, 'colB'] = pd.NaT
insrt_vals = tst_df.to_dict(orient='records')
engine = sqlalchemy.create_engine("postgresql://user:password@localhost/postgres")
connect = engine.connect()
meta = MetaData(bind=engine)
meta.reflect(bind=engine)
table = meta.tables['tstbl']
insrt_stmnt = insert(table).values(insrt_vals)
do_nothing_stmt = insrt_stmnt.on_conflict_do_nothing(index_elements=['colA','colB'])
产生错误的代码
results = engine.execute(do_nothing_stmt)
DataError: (psycopg2.DataError) invalid input syntax for type timestamp: "NaT"
LINE 1: ...6-12-18T09:54:05.046965'::timestamp, 'z5'), ('q', 'NaT'::tim...
here 提到的一种可能性是将 NaT 替换为 None,但正如之前的作者所说,这似乎有点 hackish。
sqlachemy 1.1.4
pandas 0.19.1
psycopg2 2.6.2 (dt dec pq3 ext lo64)
【问题讨论】:
NaT
只是一个特殊变量,定义为表示和处理丢失的时间。它类似于 NaN
的浮点数。我不指望它会在您尝试放置的每个地方都播放得很好。我同意,用None
替换似乎很骇人听闻……但我没有看到一种不那么骇人听闻的方法。
【参考方案1】:
您是否尝试过使用 Pandas to_sql 方法?
它适用于我的 mysql 数据库(我认为它也适用于 PostgreSQL):
In [50]: tst_df
Out[50]:
colA colB colC
0 a 2016-12-14 19:11:36.045455 a1
1 b 2016-12-15 19:11:36.045455 b2
2 c 2016-12-16 19:11:36.045455 c3
3 a 2016-12-17 19:11:36.045455 a4
4 z 2016-12-18 19:11:36.045455 z5
5 q NaT q6
In [51]: import pymysql
...: import sqlalchemy as sa
...:
In [52]:
In [52]: db_connection = 'mysql+pymysql://user:password@mysqlhost/db_name'
...:
In [53]: engine = sa.create_engine(db_connection)
...: conn = engine.connect()
...:
In [54]: tst_df.to_sql('zzz', conn, if_exists='replace', index=False)
在 MySQL 方面:
mysql> select * from zzz;
+------+---------------------+------+
| colA | colB | colC |
+------+---------------------+------+
| a | 2016-12-14 19:11:36 | a1 |
| b | 2016-12-15 19:11:36 | b2 |
| c | 2016-12-16 19:11:36 | c3 |
| a | 2016-12-17 19:11:36 | a4 |
| z | 2016-12-18 19:11:36 | z5 |
| q | NULL | q6 |
+------+---------------------+------+
6 rows in set (0.00 sec)
不幸的是,我没有用于测试的 PostgreSQL
【讨论】:
不幸的是,我正在尝试附加on conflict
或在mysql的情况下ON DUPLICATE
..熊猫不支持以上是关于如何使用 pandas sqlalchemy 和 psycopg2 处理 NaT的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Pandas 中使用 sqlalchemy 执行具有多个日期参数的 sql 存储过程
使用 SQLAlchemy 和 Pandas 插入数据 - Python
截断表不适用于 SQL Server sqlalchemy 引擎和 pandas
Pandas 和 SQLAlchemy:使用来自 engine.begin() 的连接时,带有 SQLAlchemy 2.0 fututre=True 的 df.to_sql() 会引发错误
想要使用 pandas 和 sqlalchemy 从查询是变量(不和谐用户名)的数据库中选择所有内容
无法在 ETL 过程中使用 Pandas 和 SQLAlchemy 将列名从 CSV 更改为 SQL Server DB