PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Python postgreSQL sqlalchemy fragt eine DATERANGE-Spalte ab

Die Abfrage

the_daterange_lower = datetime.strptime(the_daterange[0], '%d.%m.%Y')
the_daterange_upper = datetime.strptime(the_daterange[1], '%d.%m.%Y')

bookings = UserBooks.query.\
    filter(UserBooks.booked_date.lower >= the_daterange_lower,
           UserBooks.booked_date.upper <= the_daterange_upper).\
    all()

könnte mit dem "Bereich ist enthalten in"-Operator <@ implementiert werden . Um den richtigen Operanden zu übergeben, müssen Sie eine Instanz von psycopg2.extras.DateRange , der einen Postgresql daterange darstellt Wert in Python:

the_daterange_lower = datetime.strptime(the_daterange[0], '%d.%m.%Y').date()
the_daterange_upper = datetime.strptime(the_daterange[1], '%d.%m.%Y').date()

the_daterange = DateRange(the_dateranger_lower, the_daterange_upper)

bookings = UserBooks.query.\
    filter(UserBooks.booked_date.contained_by(the_daterange)).\
    all()

Beachten Sie, dass die Attribute lower und obere sind Teil der psycopg2.extras.Range Typen. Die Spaltentypen des SQLAlchemy-Bereichs bieten solche nicht, wie Ihre Fehlerzustände.

Wenn Sie rohes SQL verwenden und Datumsbereiche übergeben möchten, können Sie denselben DateRange verwenden Objekte, um auch Werte zu übergeben:

bookings = db_session.execute(
    'SELECT * FROM usersbookrooms WHERE booked_date && %s',
    (DateRange(the_daterange_lower, the_daterange_upper),))

Sie können auch Literale manuell erstellen , wenn Sie möchten:

bookings = db_session.execute(
    'SELECT * FROM usersbookrooms WHERE booked_date && %s::daterange',
    (f'[{the_daterange_lower}, {the_daterange_upper})',))

Der Trick besteht darin, das Literal in Python zu erstellen und als einzelnen Wert zu übergeben – wie immer mit Platzhaltern. Es sollte jegliche SQL-Injection-Möglichkeiten vermeiden; Das einzige, was passieren kann, ist, dass das Literal eine ungültige Syntax für einen daterange hat . Alternativ können Sie die Grenzen an einen Bereichskonstruktor übergeben :

bookings = db_session.execute(
    'SELECT * FROM usersbookrooms WHERE booked_date && daterange(%s, %s)',
    (the_daterange_lower, the_daterange_upper))

Alles in allem ist es einfacher, einfach die Range von Psycopg2 zu verwenden Typen und lassen Sie sie sich um die Details kümmern.