매개 변수가있는 Pandas를 사용하여 QuestDb에서 시계열 쿼리

Jan 12 2021

QuestDb에서 Pandas Dataframe으로 timeseries 데이터를로드하려고합니다. Postgres 드라이버를 다음과 같이 사용하려고합니다.

import pandas as pd
from sqlalchemy import create_engine
from datetime import datetime

engine = create_engine('postgresql://admin:quest@localhost:8812/mydb')
df = pd.read_sql_query(
  "select * from cases where ts between %(dstart)s and %(dfinish)s",
  con=engine, 
  params={"dstart":datetime(2020,12,24,16,0),"dfinish":datetime(2021,1,1,0,0)})

하지만 돌아 왔어

DatabaseError: (psycopg2.DatabaseError) between/and parameters must be constants
LINE 1: ...etry where ts between '2020-12-24T16:00:00'::timestamp ...

나는 또한 BETWEEN 대신>와 <을 사용하려고했습니다.

df = pd.read_sql_query(
  "select * from cases where ts > %(dstart)s and ts < %(dfinish)s",
  con=engine, 
  params={"dstart":datetime(2014,6,24,16,0),"dfinish":datetime(2014,6,24,17,0)})

하지만 여전히 운이 없다

DatabaseError: (psycopg2.DatabaseError) unsupported class
LINE 1: ... > '2020-06-24T16:00:00'::timestamp and ts < '2021-01-0...

매개 변수없이 작동하므로 완전히 잘못된 것은 아니지만 여기에 뭔가 빠졌습니다.

답변

4 AlexdesPelagos Jan 13 2021 at 05:40

QuestDb는 Postgres 드라이버를 지원하지만 전체 SQL 쿼리와 호환되지 않습니다. 몇 비트가 작동하지 않으므로 BETWEEN은 분명히 상수와 함께 사용할 수 있습니다. 또한 python datetime 매개 변수를 사용하면 '2020-06-24T16:00:00'::timestampQuestDb에서도 지원하지 않는 쿼리에서 변환됩니다 .

해결 방법은 문자열 매개 변수를 전달하고이를 쿼리 자체의 타임 스탬프로 변환하는 것입니다.

df = pd.read_sql_query(
  "select * from cases where ts > to_timestamp(%(dstart)s, 'yyyy-MM-dd HH:mm:ss') " + 
  "and ts < to_timestamp(%(dfinish)s, 'yyyy-MM-dd HH:mm:ss')",
  con=engine, 
  params={"dstart":datetime(2020,12,24,16,0).strftime("%Y-%m-%d %H:%M:%S"),
  "dfinish":datetime(2021,6,24,17,0).strftime("%Y-%m-%d %H:%M:%S")})

댓글에 언급 된 Trenton과 동일합니다.