我有两个这样的ORM类:
class Road(Base):
__tablename__ = "road"
id = Column(Integer, primary_key=True)
@hybrid_method
def total_traffic(self, days):
today_date = datetime.datetime.now().date()
future_date = today_date+datetime.timedelta(days)
return sum([traffic.volume
for traffic in self.traffic
if traffic.date >= today_date and traffic.date < future_date])
@total_traffic.expression
def total_traffic(cls, days):
today_date = datetime.datetime.now().date()
future_date = today_date+datetime.timedelta(days)
return select([func.sum(RoadTraffic.volume)]).\
where(RoadTraffic.road_id == cls.id).\
where(RoadTraffic.date >= today_date).\
where(RoadTraffic.date < future_date).\
label("total_traffic")
class RoadTraffic(Base):
__tablename__ = "road_traffic"
id = Column(Integer, primary_key=True)
volume = Column(Integer)
date = Column(Date, nullable=False)
road_id = Column(Integer, ForeignKey('road.id'), nullable=False)
road = relationship("Road", backref=backref('traffic'))
这在功能上非常棒,但在完整的数据集上获取所有流量数据并在本地汇总它有点慢(生产中4秒),即使使用了joinload。我可以像道路一样在道路旁边选择total_traffic:
roads_with_traffic = db.query(Orn, Orn.total_traffic(7)).all()
然后我必须改变我的观点来接受这个而不是纯粹的道路清单。
是否存在关于在相关对象上缓存所选total_traffic的约定?
答案 0 :(得分:0)
目前我对此的看法是:
class Road(Base):
__tablename__ = "road"
id = Column(Integer, primary_key=True)
def __init__(self):
self.traffic_cache = {}
@orm.reconstructor
def init_on_load(self):
self.traffic_cache = {}
@hybrid_method
def total_traffic(self, days):
if days in self.traffic_cache:
return self.traffic_cache[days]
today_date = datetime.datetime.now().date()
future_date = today_date+datetime.timedelta(days)
return sum([traffic.volume
for traffic in self.traffic
if traffic.date >= today_date and traffic.date < future_date])
@total_traffic.expression
def total_traffic(cls, days):
today_date = datetime.datetime.now().date()
future_date = today_date+datetime.timedelta(days)
return select([func.sum(RoadTraffic.volume)]).\
where(RoadTraffic.road_id == cls.id).\
where(RoadTraffic.date >= today_date).\
where(RoadTraffic.date < future_date).\
label("total_traffic")
并像这样更新Road对象:
roads_with_traffic = db.query(Road, Road.total_traffic(7)).all()
for road, traffic in roads_with_traffic:
road.traffic_cache[7] = traffic
哪个好,但是如果在课堂内移动它会更好。