pyodbc: оператор ORACLE SQL с предложением WHERE, включающим диапазон дат - PullRequest
2 голосов
/ 05 июня 2019

Я использую pyodbc для извлечения данных из таблицы базы данных. Теперь, Я хотел бы ограничить запрос только теми записями, которые были добавлены в течение последних 24 часов. Информация о времени добавления записи содержится в столбце DATE_ADDED.

Вот что я пытаюсь:

pyodbc.pooling = False
conn_str = (
    r'DRIVER={Oracle in OraClient12Home1};'
   .....
   .....
   .....)

conn = pyodbc.connect(conn_str)
curs = conn.cursor()


date_today = datetime.datetime.today()
date_yesterday = date_today - datetime.timedelta(days=1)

sql = f"SELECT PROD_ID, ID, COUNT, DATE_ADDED FROM LZE.APODAT WHERE DATE_ADDED < {date_today} AND DATE_ADDED  > {date_yesterday}"

my_df = pd.DataFrame(pd.read_sql(sql, conn))

Я получаю сообщение об ошибке:

UnicodeDecodeError: кодек «utf-16-le» не может декодировать байты в позиции 218-219: незаконное кодирование

Я уверен, что это связано с различными типами форматирования / данных столбца DATE_ADDED, но я не уверен, как к этому подойти. В базе данных это выглядит следующим образом: 2019-04-24 10:21:05 AM

Любая помощь будет принята с благодарностью.

Ответы [ 2 ]

3 голосов
/ 05 июня 2019

Рассмотрим параметризацию (отраслевой стандарт при использовании SQL на прикладном уровне), так как объект datetime Python может переводиться в тип Oracle date.

И да, вы можете параметризовать в Pandas с помощью read_sql(), используя аргумент params (который не нуждается в оболочке pd.DataFrame()).Кроме того, вам не нужны F-строки, поэтому эта версия может работать в любой версии Python.

sql = """SELECT PROD_ID, ID, COUNT, DATE_ADDED 
         FROM LZE.APODAT 
         WHERE DATE_ADDED < ? AND DATE_ADDED  > ?
      """

my_df = pd.read_sql(sql, conn, params=[date_today, date_yesterday])

В противном случае конвертировать в строку (без десятичных микросекунд) и использовать Oracle * TO_DATE():

sql = """SELECT PROD_ID, ID, COUNT, DATE_ADDED 
         FROM LZE.APODAT 
         WHERE DATE_ADDED < TO_DATE(?, 'YYYY-MM-DD HH:MI:SS')
           AND DATE_ADDED > TO_DATE(?, 'YYYY-MM-DD HH:MI:SS')?
      """

my_df = pd.read_sql(sql, conn, params=[date_today.strftime("%Y-%m-%d %H:%M:%S"), 
                                       date_yesterday.strftime("%Y-%m-%d %H:%M:%S")]
                   )
0 голосов
/ 05 июня 2019

Вы говорите, что хотите последние 24 часа ...

Вы можете сказать DATE_ADDED >= SYSDATE() - 1.0 в предложении where, чтобы получить это. SYSDATE() дает вам настоящий момент. Даты в oracle ведут себя как числа с плавающей запятой, где 1.0 - 24 часа. Таким образом, вычитая 1.0 из настоящего момента, вы получите то же самое время вчера.

Если вы хотите все с полуночи вчера, вы можете усечь дату. Используйте

DATE_ADDED >= TRUNC(SYSDATE() - 1.0)
...