Interroger les séries temporelles de QuestDb à l'aide de Pandas avec des paramètres
J'essaie de charger les données de séries chronologiques de QuestDb vers Pandas Dataframe. J'essaye d'utiliser le pilote Postgres comme
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)})
Mais reviens
DatabaseError: (psycopg2.DatabaseError) between/and parameters must be constants
LINE 1: ...etry where ts between '2020-12-24T16:00:00'::timestamp ...
J'ai aussi essayé d'utiliser> et <au lieu de 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)})
Mais toujours pas de chance
DatabaseError: (psycopg2.DatabaseError) unsupported class
LINE 1: ... > '2020-06-24T16:00:00'::timestamp and ts < '2021-01-0...
Cela fonctionne sans paramètres, donc ce n'est pas tout à fait faux, mais il me manque quelque chose ici.
Réponses
QuestDb prend en charge le pilote Postgres mais n'est pas entièrement compatible avec les requêtes SQL. Peu de bits ne fonctionnent pas, donc BETWEEN ne peut apparemment être utilisé qu'avec des constantes. De plus, lorsque vous utilisez des paramètres datetime python, ils sont convertis '2020-06-24T16:00:00'::timestamp
dans la requête, ce qui n'est pas non plus pris en charge par QuestDb
La solution de contournement consiste à transmettre des paramètres de chaîne et à les convertir en horodatage dans la requête elle-même, quelque chose comme
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")})
C'est la même chose que dans le Trenton mentionné dans les commentaires.