【问题标题】:Python cx_oracle conversion from varchar2 to date - Error "sqlalchemy.exc.DatabaseError: (cx_Oracle.DatabaseError) ORA-01861"从 varchar2 到日期的 Python cx_oracle 转换 - 错误“sqlalchemy.exc.DatabaseError: (cx_Oracle.DatabaseError) ORA-01861”
【发布时间】:2020-07-20 17:31:18
【问题描述】:

使用 python sqlalchemy 从 Oracle 数据库读取 - 对于在源中存储为 "varchar2""Date" 字段。

示例:Oracle“2019-12-20”中的 Test_col 格式。这在源数据库中存储为 varchar2。

仅供参考:在 python 中将“varchar2 转换为日期”:

var_1: datetime.strptime('2019-12-20','%Y-%m-%d').date()

将 var_1 传递给下面的 sql,最终如下所示:

select * 
FROM stg_test_table 
WHERE to_date(Test_col,'YYYY-MM-DD') = '2019-12-20'

如果我从 Oracle 开发人员运行但从 Python 代码运行相同,则运行良好,会出现以下错误:

sqlalchemy.exc.DatabaseError: (cx_Oracle.DatabaseError) 
ORA-01861: literal does not match format string

尝试了多个日期组合,但从 Python 运行时似乎没有一个有效。

这可以链接到 cx_oracle 版本问题吗?

【问题讨论】:

  • 你有没有试过用date'2019-12-20'代替'2019-12-20' ..?
  • 是的,我做到了,但这也不起作用。

标签: python-3.x oracle sqlalchemy cx-oracle


【解决方案1】:

当日期存储为字符串时会发生这种情况。尽管大多数“日期”都有正确的格式,但您预测的格式是:YYYY-MM-DD,但并非所有日期都如此。

例如,如果有人将今天的日期输入为08042020,并且您应用了上述格式掩码,您会得到

SQL> select to_date('08042020', 'yyyy-mm-dd') from dual;
select to_date('08042020', 'yyyy-mm-dd') from dual
               *
ERROR at line 1:
ORA-01861: literal does not match format string


SQL>

怎么办?期待(很多?)修复数据的痛苦。希望它会教您(以及参与此操作的其他人)将日期存储到 DATE 列中。

例如,您可以使用正则表达式“拦截”无效格式(期望 4 位 - 2 位 - 2 位),但它对 2020-34-87 的值没有帮助,因为它符合格式,但废话。

或者,您可以循环遍历这些值(逐行表示缓慢)并丢弃 TO_DATE 失败的值。

您可以尝试不同的格式掩码,例如YYYYMMDD,但是 - 从 20200408 开始,04 是什么,08 是什么?两者都可以是几天或几个月。

正如我所说,没有简单的方法。

【讨论】:

  • 感谢您的详细回答,但我确实尝试运行一条记录(为此我可以在源数据库中看到确切的格式 - 'YYYY'MM'DD'),为此我也我面临同样的问题。
【解决方案2】:

好的,所以我能够解决这个问题,这里的关键是传递您的数据库所期望的格式,您可以通过以下方式检查:

从 v$nls_parameters 中选择值,其中 parameter = 'NLS_DATE_FORMAT';

考虑到您传递的格式正确,使用通常的 TO_DATE 转换进行隐蔽,这应该可以工作。

【讨论】:

    猜你喜欢
    • 2017-09-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-07
    • 1970-01-01
    • 2018-10-05
    • 1970-01-01
    • 1970-01-01
    • 2016-09-22
    相关资源
    最近更新 更多