Zapytanie
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()
można zaimplementować za pomocą operatora „zakres zawiera się w” <@
. Aby przekazać właściwy operand, musisz utworzyć instancję psycopg2.extras.DateRange
, który reprezentuje daterange
Postgresql wartość w Pythonie:
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()
Zwróć uwagę, że atrybuty lower
i upper
są częścią psycopg2.extras.Range
typy. Typy kolumn zakresu SQLAlchemy nie zapewniają takich, jak stwierdza błąd.
Jeśli chcesz używać surowego kodu SQL i zakresów dat przekazywania, możesz użyć tego samego DateRange
obiekty do przekazywania wartości:
bookings = db_session.execute(
'SELECT * FROM usersbookrooms WHERE booked_date && %s',
(DateRange(the_daterange_lower, the_daterange_upper),))
Możesz też ręcznie budować literały , jeśli chcesz:
bookings = db_session.execute(
'SELECT * FROM usersbookrooms WHERE booked_date && %s::daterange',
(f'[{the_daterange_lower}, {the_daterange_upper})',))
Sztuczka polega na zbudowaniu literału w Pythonie i przekazaniu go jako pojedynczej wartości – jak zwykle przy użyciu symboli zastępczych. Powinno unikać wszelkich możliwości wstrzykiwania SQL; jedyną rzeczą, która może się zdarzyć, jest to, że literał ma nieprawidłową składnię dla daterange
. Alternatywnie możesz przekazać granice do konstruktora zakresu
:
bookings = db_session.execute(
'SELECT * FROM usersbookrooms WHERE booked_date && daterange(%s, %s)',
(the_daterange_lower, the_daterange_upper))
Podsumowując, łatwiej jest po prostu użyć Range
Psycopg2 typy i pozwól im zająć się szczegółami.