Pandalar kullanarak QuestDb'den zaman serilerini parametrelerle sorgulama

Jan 13 2021

Zaman serisi verilerini QuestDb'den Pandas Dataframe'e yüklemeye çalışıyorum. Postgres sürücüsünü şu şekilde kullanmaya çalışıyorum

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)})

Ama geri döndüm

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

Ayrıca BETWEEN yerine> ve <kullanmayı denedim

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)})

Ama hala şans yok

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

Parametreler olmadan çalışıyor, bu yüzden tamamen yanlış değil ama burada bir şey eksik.

Yanıtlar

4 AlexdesPelagos Jan 13 2021 at 05:40

QuestDb, Postgres sürücü desteğine sahiptir ancak tam SQL sorgusu uyumlu değildir. Birkaç bit çalışmaz, bu yüzden BETWEEN görünüşe göre sadece sabitlerle kullanılabilir. Ayrıca python datetime parametrelerini kullandığınızda, bunlar '2020-06-24T16:00:00'::timestampQuestDb tarafından desteklenmeyen sorguda dönüştürülür.

Çözüm, dize parametrelerini iletmek ve bunları sorgunun kendisinde zaman damgasına dönüştürmektir.

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")})

Yorumlarda bahsedilen Trenton'daki ile aynı.