如何使用Python+;熊猫?

如何使用Python+;熊猫?,python,excel,oracle,pandas,Python,Excel,Oracle,Pandas,我有一个Python应用程序,它使用pandas搜索一些excel电子表格,并将值插入oracle数据库 对于具有值的日期单元格,这可以正常工作。对于空的日期单元格,我插入了一个NaT,我本以为这会很好,但在Oracle中,这会变成一个奇怪的无效时间,显示为“0001-255-255 00:00:00”(我猜是MAXINT或0转换为时间戳?) 上面是数据帧中的数据位,您可以看到它是一个NaT 但这就是我在甲骨文中看到的 SQL> select TDATE from TABLE where

我有一个Python应用程序,它使用pandas搜索一些excel电子表格,并将值插入oracle数据库

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

上面是数据帧中的数据位,您可以看到它是一个NaT

但这就是我在甲骨文中看到的

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转换为None,但我发现其中任何一个都有各种各样的错误,这似乎意味着以这种方式进行替换是无效的


有没有办法确保这些数据存储中空日期的一致性

我希望Oracle数据库中日期列的数据类型是
date

在这种情况下,请记住,日期有日期部分和时间部分作为日期。在加载到数据库时,请确保使用
来指定日期
,并为日期文本设置正确的日期时间格式

那是关于装载的。现在,要显示,请使用具有适当日期时间格式的
to_CHAR
,以人眼希望看到日期时间值的方式查看值


而且,关于
NULL
值,除非您有
notnull
约束,否则我看不出加载有任何问题。
NULL
值无论如何都会加载为NULL。如果要操作
NULL
值,请使用
NVL
函数并使用所需的值替换NULL值。

此问题已在Pandas 15.0中修复。

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


在进行了一些实验之后,熊猫似乎将
NaT
传给了SQLAlchemy,然后传给了cx_Oracle——后者又盲目地向Oracle发送了一个无效的日期(后者又不抱怨)

不管怎样,我能提供的一个方法是在插入触发器之前添加一个
,以修复传入的时间戳。要使其工作,您必须首先手动创建表

-- 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中,使用:

并检查:

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

如何在数据库中插入日期值?日期列的类型是什么?欢迎使用堆栈溢出。请看我的答案,如果你有任何悬而未决的问题,请在我的答案上发表评论:-)@SylvainLeroux In[231]:x['TDATE'].dtype Out[229]:dtype('我尝试了将近1/2小时,但我无法重现那种行为(即:“伪造”日期以产生与你相同的“转储”).您是否使用将数据帧发送到DB?或其他什么?不,出于太深奥的原因,我正在对数据帧进行一点处理,并实际使用光标直接执行sql。鉴于您没有看到sql的wierdness。对于sql,可能值得我测试该方法。如果它有效,我可以解决导致我使用sql的问题请使用光标。“我希望Oracle数据库中日期列的数据类型是日期。”根据
DUMP
输出,这是一个感谢!尽管我还不能升级pandas(目前离uprev主要组件的发布太近了),使用你们给我的一系列建议,我能够在短期内克服这个问题。长期的提升熊猫已经在计划中,所以这会更好。谢谢!
>>> 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)