Python cx_ oracle преобразование из varchar2 в дату - ошибка "sqlalchemy.ex c .DatabaseError: (cx_ Oracle .DatabaseError) ORA-01861" - PullRequest
0 голосов
/ 08 апреля 2020

Чтение из базы данных Oracle с использованием python sqlalchemy - для поля "Дата" , сохраненного как "varchar2" в источнике.

Пример: Test_col в формате Oracle "2019-12-20". Это сохраняется как varchar2 в исходной БД.

FYI: преобразование "varchar2 в дату" в python:

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?

Ответы [ 2 ]

0 голосов
/ 09 апреля 2020

хорошо, так что я смог решить эту проблему, ключевая вещь здесь - передать формат, ожидаемый вашей БД, вы можете проверить это следующим образом:

выберите значение из v $ nls_parameters, где параметр = 'NLS_DATE_FORMAT';

Учитывая, что вы передаете правильный формат, скрывайте, используя обычные преобразования TO_DATE, и это должно работать.

0 голосов
/ 08 апреля 2020

Вот что происходит, когда даты хранятся в виде строк. Хотя большинство «дат» имеют правильный формат, который вы предсказали: 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, потому что это соответствует формату, но это чепуха.

Или, вы можете l oop через эти значения (то есть строка -by-row означает «медленно-медленно» и сбрасывает значения, для которых TO_DATE не удается.

Вы можете попробовать маски разных форматов, например, YYYYMMDD, но - с 20200408, что такое 04, а что 08? И то, и другое может быть днями или месяцами.

Как я уже сказал, легкого выхода из этого не существует.

...