Thời gian truy vấn từ QuestDb bằng cách sử dụng Pandas với các tham số

Jan 13 2021

Tôi đang cố tải dữ liệu thời gian chờ từ QuestDb sang Pandas Dataframe. Tôi đang cố gắng sử dụng trình điều khiển Postgres như

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

Nhưng đã trở lại

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

Tôi cũng đã cố gắng sử dụng> và <thay vì 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)})

Nhưng vẫn không gặp may

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

Nó hoạt động mà không có tham số vì vậy nó không hoàn toàn sai nhưng tôi đang thiếu một cái gì đó ở đây.

Trả lời

4 AlexdesPelagos Jan 13 2021 at 05:40

QuestDb có hỗ trợ trình điều khiển Postgres nhưng không tương thích với truy vấn SQL đầy đủ. Một số bit không hoạt động nên GIỮA dường như chỉ có thể được sử dụng với các hằng số. Ngoài ra, khi bạn sử dụng các tham số ngày giờ trong python, chúng được chuyển đổi thành '2020-06-24T16:00:00'::timestamptrong truy vấn cũng không được QuestDb hỗ trợ

Cách giải quyết là chuyển các tham số chuỗi và chuyển đổi chúng thành dấu thời gian trong chính truy vấn, giống như

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

Điều đó cũng giống như ở Trenton được đề cập trong các bình luận.