2012-12-20 2 views
1

내가 두 ORM의이 같은 클래스가 :이 기능 환상적이지만 전체 데이터 세트의 모든 트래픽 데이터를 얻고 로컬로 합산에 비트가SqlAlchem ​​y의 : 관련 오브젝트 캐싱 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 초).

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

을하지만 그때 나는 순수한 도로 목록 대신이 수신을 내보기를 변경해야 : 그래서 같은 도로와 함께 total_traffic 선택할 수 있습니다.

관련 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 

하지만 내이 이동 좋을 것이다 어떤 방법으로 수업.