La consulta
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()
podría implementarse usando el operador "el rango está contenido en" <@
. Para pasar el operando correcto, debe crear una instancia de psycopg2.extras.DateRange
, que representa un daterange
de Postgresql valor 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()
Tenga en cuenta que los atributos lower
y upper
son parte del psycopg2.extras.Range
tipos Los tipos de columnas de rango de SQLAlchemy no proporcionan tales, como indica su error.
Si desea usar SQL sin procesar y pasar rangos de fechas, puede usar el mismo DateRange
objetos para pasar valores también:
bookings = db_session.execute(
'SELECT * FROM usersbookrooms WHERE booked_date && %s',
(DateRange(the_daterange_lower, the_daterange_upper),))
También puede construir literales manualmente , si quieres:
bookings = db_session.execute(
'SELECT * FROM usersbookrooms WHERE booked_date && %s::daterange',
(f'[{the_daterange_lower}, {the_daterange_upper})',))
El truco es construir el literal en Python y pasarlo como un valor único, usando marcadores de posición, como siempre. Debería evitar cualquier posibilidad de inyección SQL; lo único que puede suceder es que el literal tenga una sintaxis no válida para un daterange
. Alternativamente, puede pasar los límites a un constructor de rango
:
bookings = db_session.execute(
'SELECT * FROM usersbookrooms WHERE booked_date && daterange(%s, %s)',
(the_daterange_lower, the_daterange_upper))
En general, es más fácil usar el Range
de Psycopg2 tipos y déjelos manejar los detalles.