2017-01-21 6 views
2

Ive는 아래에 표시된 두 모델 BasketBasketItem을 만들었습니다. 바구니에는 많은 바구니 항목이 있으므로 외래 키를 사용하여이 관계를 만들 수 있습니다.Python SQLAlchemy - 자식 업데이트시 상위 모델의 타임 스탬프 업데이트

Basket 모델에는 바구니가 마지막으로 업데이트 된 시간 스탬프를 보유하는 updated_at 필드가 있음을 알 수 있습니다. BasketItem이 추가, 제거 또는 업데이트 될 때이 필드를 업데이트하고 싶습니다.

이벤트 리스너를 추가했지만 솔루션이 너무 우아하지 않습니다. 이 작업을 수행하는 더 좋은 방법이 있습니까?

class Basket(Base): 
    __tablename__ = "baskets" 

    id = Column(String(45), primary_key=True, default=uuid4) 
    shop = Column(String(45), nullable=False) 
    currency_code = Column(String(3), nullable=False) 
    total = Column(String(15), nullable=False, default=0) 
    status = Column(Enum("open", "closed"), nullable=False, default="open") 
    created_at = Column(DateTime, default=datetime.datetime.utcnow) 
    updated_at = Column(DateTime, default=datetime.datetime.now, onupdate=datetime.datetime.utcnow) 

    items = relationship("BasketItem", backref="basket") 


class BasketItem(Base): 
    __tablename__ = "basket_items" 

    basket_id = Column(String(45), ForeignKey('baskets.id'), primary_key=True) 
    product_url = Column(String(90), nullable=False, primary_key=True) 
    quantity = Column(Integer, nullable=False) 

@event.listens_for(BasketItem, 'after_insert') 
@event.listens_for(BasketItem, 'after_update') 
@event.listens_for(BasketItem, 'after_delete') 
def basket_item_change(mapper, connection, target): 
    db_session = scoped_session(sessionmaker(autocommit=False, autoflush=False, bind=engine)) 
    basket = db_session.query(Basket).get(target.basket_id) 
    basket.updated_at = datetime.datetime.utcnow() 
    db_session.commit() 

답변

1

나는 이벤트 리스너를 사용하는 것이 좋다고 생각하지만 아래처럼 할 수 있습니다. 새 basketitem을 추가 할 때 먼저 쿼리 부모가 될 것이라고 확신하고 그 부모와 함께이 자식을 추가하십시오. 예인 경우 :

basket = Basket.query.get(id) 
if basket: 
    basket.update() 
    # you can perform delete or update too 
    item = BasketItem(basket=basket, ...) 
    db.session.add(item) 
    db.session.commit() 

class Basket(db.Model): 
    ... 
    def update(self): 
     self.updated_at = datetime.utcnow() 
     db.session.add(self) 
     db.session.commit()