La requête
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()
pourrait être implémenté en utilisant l'opérateur "la plage est contenue par" <@
. Afin de passer le bon opérande, vous devez créer une instance de psycopg2.extras.DateRange
, qui représente un daterange
Postgresql valeur en 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()
Notez que les attributs lower
et upper
font partie de la psycopg2.extras.Range
les types. Les types de colonne de plage SQLAlchemy ne fournissent pas de tels, comme l'indique votre erreur.
Si vous souhaitez utiliser du SQL brut et transmettre des plages de dates, vous pouvez utiliser le même DateRange
objets pour transmettre également des valeurs :
bookings = db_session.execute(
'SELECT * FROM usersbookrooms WHERE booked_date && %s',
(DateRange(the_daterange_lower, the_daterange_upper),))
Vous pouvez également créer des littéraux manuellement , si vous souhaitez :
bookings = db_session.execute(
'SELECT * FROM usersbookrooms WHERE booked_date && %s::daterange',
(f'[{the_daterange_lower}, {the_daterange_upper})',))
L'astuce consiste à construire le littéral en Python et à le transmettre en tant que valeur unique - en utilisant des espaces réservés, comme toujours. Il doit éviter toute possibilité d'injection SQL ; la seule chose qui peut arriver est que le littéral a une syntaxe invalide pour un daterange
. Vous pouvez également passer les limites à un constructeur de plage
:
bookings = db_session.execute(
'SELECT * FROM usersbookrooms WHERE booked_date && daterange(%s, %s)',
(the_daterange_lower, the_daterange_upper))
Dans l'ensemble, il est plus facile d'utiliser simplement la Range
Psycopg2 types et laissez-les gérer les détails.