如何使用Python + Pandas将空的exceldate插入到oracle中?

我有一个Python应用程序使用pandas来挖掘一些Excel电子表格,并将值插入到Oracle数据库中。

对于具有值的date单元格,这工作正常。 对于空白的date单元格,我插入一个NaT,我原以为会很好,但是在Oracle中正在变成一个奇怪的无效时间,显示为“0001-255-255 00:00:00”(类似于MAXINT或0被转换为时间戳我猜?)

In[72]: x.iloc[0][9] Out[72]: NaT 

以上是DataFrame中的一些数据,你可以看到它是一个NaT。

但这是我在Oracle看到的

 SQL> select TDATE from TABLE where id=5067 AND version=5; TDATE --------- 01-NOVEMB SQL> select dump("TDATE") TABLE where id=5067 AND version=5; DUMP("TDATE") -------------------------------------------------------------------------------- Typ=12 Len=7: 100,101,255,255,1,1,1 

我试图做df.replace和/或df.where将NaT转换为无,但我得到任何错误与这些似乎暗示替代无效的方式。

任何方式来确保跨这些数据存储的空date的一致性?

这个问题已经在pandas15.0中得到解决。

如果可以的话,更新到Pandas> = 15.0。 从该版本开始, NaNNaT在数据库中正确存储为NULL。


在进行了一些实验之后,Pandas似乎将NaT传递给了SQLAlchemy,然后又传递到了cx_Oracle–它又将一个无效的date盲目地发送给Oracle(这反过来又不会抱怨)。

无论如何,我能够一起来添加一个BEFORE INSERT TRIGGER来修复传入的时间戳。 为了这个工作,你将不得不手动创build表格。

 -- 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; / 

之后,从Python,使用pandas.DataFrame.toSql(..., if_exists='append')

 >>> 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) 

请注意,如果您需要将其他DataFrame重写到同一个表中,则首先需要删除它的内容,但不要删除它,否则会同时丢失触发器。 例如:

 # 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) 

我希望Oracle数据库中date列的数据types是DATE

在这种情况下,请记住,date的date部分和时间部分一起作为date。 在加载到数据库时,请确保使用TO_DATE并将date时间格式设置为date文字。

这是关于加载。 现在,要显示具有适当的date时间格式的TO_CHAR ,以人眼想要查看date时间值的方式查看值。

而且,关于NULL值,除非你有NOT NULL约束,我没有看到加载的问题。 NULL值将反正加载为NULL。 如果要操作NULL值,请使用NVL函数并使用所需值replaceNULL值。