此问题已在Pandas 15.0中修复。
如果可以,更新到Pandas> = 15.0。从该版本开始,NaN和NaT在数据库中正确存储为NULL。
已经进行了一些实验后,似乎熊猫传递NaT到SQLAlchemy的和向下cx_Oracle - 这反过来一味发送无效日期甲骨文(这反过来不抱怨)。
无论如何,我能找到的是添加一个BEFORE INSERT TRIGGER来修复传入的时间戳。为此,您必须首先手动创建表格。
-- Create the table
CREATE TABLE W ("ID" NUMBER(5), "TDATE" TIMESTAMP);
然后扳机:
-- Create a trigger on the table
CREATE OR REPLACE TRIGGER fix_null_ts
BEFORE INSERT ON W
FOR EACH ROW WHEN (extract(month from new.tdate) = 255)
BEGIN
:new.tdate := NULL;
END;
/
>>> d = [{"id":1,"tdate":datetime.now()},{"id":2}]
>>> f = pd.DataFrame(d)
>>> f.to_sql("W",engine, if_exists='append', index=False)
# ^^^^^^^^^^^^^^^^^^
# don't drop the table! append data to an existing table
并检查:
>>> result = engine.execute("select * from w")
>>> for row in result:
... print(row)
...
(1, datetime.datetime(2014, 10, 31, 1, 10, 2))
(2, None)
要注意的是,如果你需要的其他数据帧重写到同一个表,你首先需要删除的内容 - 而不是放弃它,否则你会在同一时间失去了扳机。例如:
# Some new data
>>> d = [{"id":3}]
>>> f = pd.DataFrame(d)
# Truncate the table and write the new data
>>> engine.execute("truncate table w")
>>> f.to_sql("W",engine, if_exists='append', index=False)
>>> result = engine.execute("select * from w")
# Check the result
>>> for row in result:
... print(row)
...
(3, None)