Запрос Python PostgreSQL с фильтрацией по столбцу timestamptz

#python #postgresql

#python #postgresql

Вопрос:

Я пытаюсь извлечь данные из базы данных PostgreSQL, фильтруя их по столбцу timestamptz, используя как дату, так и время.

Пример значения столбца DB timestamptz: 2020-12-11 17:18:34

Я могу извлекать данные, если использую только даты.

Это возвращает значения в диапазоне дат :

 start_date = '2020-12-11'
end_date = '2020-12-12'
result = pd.read_sql_query(f"""select *
                          from public."userActionsLogs" ual
                          where "timestamp" BETWEEN '{start_date}' and '{end_date}'
                          order by "timestamp" ASC""", conn)
 

Это возвращает пустой список :

 start_date = '2020-12-11 16:10:00'
end_date = '2020-12-11 17:21:00'
result = pd.read_sql_query(f"""select *
                          from public."userActionsLogs" ual
                          where "timestamp" BETWEEN '{start_date}' and '{end_date}'
                          order by "timestamp" ASC""", conn)
 

Что я пробовал и не получил результатов:

 pd.read_sql_query(f"""select *
                      from public."userActionsLogs" ual
                      where to_char("timestamp", 'YYYY-MM-DD HH24:MI:SS') BETWEEN 
                      '{start_date}' and '{end_date}'
                      order by "timestamp" ASC""", conn)
 

Любой ввод высоко ценится.

Заранее благодарю.

Комментарии:

1. Действительно ли поле «timestamp» является timestamptz типом? Работает ли запрос, если вы его запустите psql ?

2. Да, поле «отметка времени» имеет тип timestamptz . Я использую DBeaver в качестве редактора SQL и использую тот же запрос в редакторе, который я отправляю из python, возвращает результаты.

Ответ №1:

Этот блок, который вы записали, является правильным. Но я думаю, что вы забыли экранировать символы «‘ «. Попробуйте это:

 pd.read_sql_query(f"""select *
                      from public."userActionsLogs" ual
                      where to_char("timestamp", 'YYYY-MM-DD HH24:MI:SS') BETWEEN 
                      '{start_date}' and '{end_date}'
                      order by "timestamp" ASC""", conn) 
 

Комментарии:

1. К сожалению, он по-прежнему возвращает пустой DF. Я также попытался выполнить запрос с помощью psycopg2 вместо pandas, и результатом по-прежнему является пустой список.

Ответ №2:

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

 import datetime
import pytz
import pandas as pd

start_date = '2020-12-11 16:10:00'
end_date = '2020-12-11 17:21:00'
tz = pytz.timezone('Europe/Athens')

start = datetime.datetime.strptime(start_date, '%Y-%m-%d %H:%M:%S')
start = start.replace(tzinfo=tz)

end = datetime.datetime.strptime(end_date, '%Y-%m-%d %H:%M:%S')
end = end.replace(tzinfo=tz)

result = pd.read_sql_query(f"""select *
                          from public."userActionsLogs" ual
                          where "timestamp" BETWEEN '{start}' and '{end}'
                          order by "timestamp" ASC""", conn)
 

Комментарии:

1. Не могли бы вы просто сделать:pd.read_sql_query(«»»выберите * из public.»userActionsLogs» ual, где «временная метка» МЕЖДУ %(start)s и %(end}s по порядку «timestamp» ASC»»», conn, params={«start»: start_date},»конец»: end_date)

2. Понял, что забыл важную часть. Это должно быть: BETWEEN %(start)s and %(end}s AT TIME ZONE 'Europe/Athens' .

3. @AdrianKlaver Я проверил ваше предложение. start_date = '2020-12-15 14:50:00' end_date = '2020-12-31 14:50:00' pd.read_sql_query("""select * from public."userActionsLogs" ual where "timestamp" BETWEEN %(start)s and %(end)s AT TIME ZONE 'Europe/Athens' order by "timestamp" ASC""", conn, params={"start": start_date, "end": end_date}) Out[16]: Empty DataFrame Columns: [id, timestamp, userId, email, eventType] Index: [] В любом случае спасибо за ваш вклад.

4. Запустите запрос непосредственно psql и посмотрите, что вы получите? Также что SELEC T '2020-12-15 14:50:00'::timestamp AT TIME ZONE ''Europe/Athens' получается? Что TimeZone установлено для сервера Postgres?