2017-01-21 13 views
2

BasketItemという2つのモデルを作成しました。バスケットには多くのバスケットアイテムがあるので、この関係を作成するために外部キーを使用しています。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

私はイベントリスナーを使用すると良いと思いますが、以下のようにすることができます。新しいバスケットアイテムを追加するときは、最初にクエリの親であることを確認してから、その親にこの子を追加してください。はいの場合:

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() 
関連する問題