2012-12-20 55 views
1

我有兩個ORM類是這樣的:的SQLAlchemy:緩存hybrid_method導致相關對象

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秒)。我可以像這樣的道路旁邊選擇total_traffic:

roads_with_traffic = db.query(Orn, Orn.total_traffic(7)).all() 

但後來我不得不改變我的觀點獲得這個,而不是純粹的數據列表。

是否有關於在相關對象上緩存所選total_traffic的約定?

回答

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") 

和更新道對象,像這樣:

roads_with_traffic = db.query(Road, Road.total_traffic(7)).all() 
for road, traffic in roads_with_traffic: 
    road.traffic_cache[7] = traffic 

這是不錯,但它會是不錯的內部推動這一該課如何。