Kueri rentang waktu dari QuestDb menggunakan Pandas dengan parameter

Jan 13 2021

Saya mencoba memuat data rangkaian waktu dari QuestDb ke Pandas Dataframe. Saya mencoba menggunakan driver Postgres seperti

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

Tapi kembali

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

Saya juga mencoba menggunakan> dan <daripada ANTARA

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

Tapi tetap saja tidak berhasil

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

Ia bekerja tanpa parameter jadi tidak sepenuhnya salah tapi saya melewatkan sesuatu di sini.

Jawaban

4 AlexdesPelagos Jan 13 2021 at 05:40

QuestDb memiliki dukungan driver Postgres tetapi tidak kompatibel dengan kueri SQL penuh. Beberapa bit tidak berfungsi sehingga ANTARA tampaknya hanya dapat digunakan dengan konstanta. Juga ketika Anda menggunakan parameter datetime python, mereka dikonversi ke '2020-06-24T16:00:00'::timestampdalam kueri yang juga tidak didukung oleh QuestDb

Solusinya adalah dengan meneruskan parameter string dan mengonversinya menjadi stempel waktu dalam kueri itu sendiri, seperti

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

Itu sama seperti di Trenton yang disebutkan di komentar.