我正在尝试构建一个过滤酒店价格列表的查询。我只想显示今天和未来的酒店预订。我构建的查询在下面但不过滤结果。我做错了什么?
hotels = db.session.query(Hotel).\
join(Location).\
join(Rate).\
filter(Location.city == city).\
filter(Rate.arrive > datetime.utcnow())
对于背景,我的模型看起来像这样:
class Location(Base):
__tablename__ = 'locations'
id = Column(Integer, primary_key=True)
city = Column(String(50), nullable=False, unique=True)
hotels = relationship('Hotel', back_populates='location')
class Hotel(Base):
__tablename__ = 'hotels'
id = Column(Integer, primary_key=True)
name = Column(String(100), nullable=False, unique=True)
phone_number = Column(String(20))
parking_fee = Column(String(10))
location_id = Column(Integer, ForeignKey('locations.id'), nullable=False)
location = relationship('Location', back_populates='hotels')
rates = relationship('Rate', back_populates='hotel', order_by='Rate.arrive')
class Rate(Base):
__tablename__ = 'rates'
id = Column(Integer, primary_key=True)
price = Column(Numeric(6, 2))
arrive = Column(Date, nullable=False)
link = Column(String(500), nullable=False)
updated = Column(DateTime, default=datetime.datetime.utcnow, nullable=False)
hotel_id = Column(Integer, ForeignKey('hotels.id'), nullable=False)
hotel = relationship('Hotel', back_populates='rates')
编辑: 以下是一些示例数据:
Date: Friday, Sep 9
Rate: 299.25
Date: Sunday, Sep 11
Rate: 261.75
Date: Monday, Sep 12
Rate: 261.75
Date: Tuesday, Sep 13
Rate: 261.75
Date: Sunday, Sep 18
删除过滤器(Rate.arrive> datetime.utcnow())不会更改数据。每次运行查询时输出都相同。
答案 0 :(得分:1)
选项零是在您加载酒店后应用费率过滤器,但这会生成其他查询,并且不需要。
定义稍后使用的过滤器:
city = 'mumbai'
arrive = datetime.date.today()
选项-1:在初始查询中加载感兴趣的Rate
query = (
session.query(Hotel, Rate) # this query will return pairs (Hotel, Rate)
.join(Location)
.join(Rate)
.filter(Location.city == city)
.filter(Rate.arrive > arrive)
)
# one could use the results directly as (Hotel, Rate) pairs
# but we can also convert to the format: {hotel: rates}
from collections import defaultdict
hotels_list = defaultdict(list)
for h, r in hotels:
hotels_list[h].append(r)
# and print:
for hotel, rates in hotels_list.items():
print('', hotel)
for rate in rates:
print(' ', rate)
选项-2:欺骗关系Hotel.rates
我们正在使用contains_eager
hotels = (
session.query(Hotel)
.join(Location)
.join(Rate)
.options(contains_eager(Hotel.rates)) # this is the key
.filter(Location.city == city)
.filter(Rate.arrive > arrive)
)
for hotel in hotels:
print('', hotel)
for rate in hotel.rates: # this now contains only sub-list, so be careful
print(' ', rate)