Я пытаюсь извлечь данные из базы данных PostgreSQL, фильтруя их по столбцу 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)
Любой вклад высоко ценится.
Заранее спасибо.
Да, поле «timestamp» имеет тип timestamptz. Я использую DBeaver в качестве редактора SQL и использую тот же запрос в редакторе, который я отправляю из python, возвращает результаты.
Этот блок, который вы написали, правильный. Но я думаю, что вы забыли избежать символов " ' ". Попробуй это:
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)
К сожалению, он по-прежнему возвращает пустой DF. Я также попытался выполнить запрос с помощью psycopg2 вместо pandas, и результатом по-прежнему остается пустой список.
Для тех, кто столкнулся с этой проблемой, решение следующее:
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)
Не могли бы вы просто сделать: pd.read_sql_query("""select * from public."userActionsLogs" ual, где "timestamp" МЕЖДУ %(start)s и %(end}s в порядке "timestamp" ASC""", conn , params = {"start": start_date}, "end": end_date)
Понял, что забыл важную часть. Должно быть: BETWEEN %(start)s and %(end}s AT TIME ZONE 'Europe/Athens'
.
@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: []
Спасибо за ваш вклад в любом случае.
Запустите запрос прямо в psql
и посмотрите, что вы получите? И что SELEC T '2020-12-15 14:50:00'::timestamp AT TIME ZONE ''Europe/Athens'
получает? Что установлено TimeZone
для сервера Postgres?
Является ли поле «отметка времени» типом
timestamptz
? Будет ли работать запрос, если вы запустите его вpsql
?