A pergunta
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()
pode ser implementado usando o operador "intervalo contido por"
<@
. Para passar o operando correto, você precisa criar uma instância de psycopg2.extras.DateRange
, que representa um daterange
do Postgresql valor em 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()
Observe que os atributos
lower
e upper
fazem parte do psycopg2.extras.Range
tipos. Os tipos de coluna de intervalo SQLAlchemy não fornecem isso, conforme seu erro indica. Se você quiser usar SQL bruto e passar intervalos de datas, você pode usar o mesmo
DateRange
objetos para passar valores também:bookings = db_session.execute(
'SELECT * FROM usersbookrooms WHERE booked_date && %s',
(DateRange(the_daterange_lower, the_daterange_upper),))
Você também pode criar literais manualmente , se você quiser:
bookings = db_session.execute(
'SELECT * FROM usersbookrooms WHERE booked_date && %s::daterange',
(f'[{the_daterange_lower}, {the_daterange_upper})',))
O truque é construir o literal em Python e passá-lo como um valor único – usando espaços reservados, como sempre. Deve evitar qualquer possibilidade de injeção de SQL; a única coisa que pode acontecer é que o literal tenha uma sintaxe inválida para um
daterange
. Como alternativa, você pode passar os limites para um construtor de intervalo
:bookings = db_session.execute(
'SELECT * FROM usersbookrooms WHERE booked_date && daterange(%s, %s)',
(the_daterange_lower, the_daterange_upper))
Em suma, é mais fácil usar o Psycopg2
Range
tipos e deixá-los lidar com os detalhes.