出于性能原因,我有一个非规范化数据库,其中一些表包含从其他表中的许多行聚合的数据.我想通过使用SQLAlchemy事件来维护这个非规范化的数据缓存.例如,假设我正在编写论坛软件,并希望每个Thread
人都有一个列跟踪线程中所有注释的组合字数,以便有效地显示该信息:
class Thread(Base):
id = Column(UUID, primary_key=True, default=uuid.uuid4)
title = Column(UnicodeText(), nullable=False)
word_count = Column(Integer, nullable=False, default=0)
class Comment(Base):
id = Column(UUID, primary_key=True, default=uuid.uuid4)
thread_id = Column(UUID, ForeignKey('thread.id', ondelete='CASCADE'), nullable=False)
thread = relationship('Thread', backref='comments')
message = Column(UnicodeText(), nullable=False)
@property
def word_count(self):
return len(self.message.split())
Run Code Online (Sandbox Code Playgroud)
因此,每次插入注释时(为简单起见,我们都要说注释永远不会被编辑或删除),我们希望更新word_count
相关Thread
对象的属性.所以我想做点什么
def after_insert(mapper, connection, target):
thread = target.thread
thread.word_count = sum(c.word_count for c in thread.comments)
print "updated cached word count to", thread.word_count
event.listen(Comment, "after_insert", after_insert)
Run Code Online (Sandbox Code Playgroud)
因此,当我插入a时Comment
,我可以看到事件触发并看到它已正确计算字数,但该更改未保存到Thread …
我需要一些帮助来自动化 sqlalchemy 中的一些任务。当新用户在我的网站上注册时,我需要添加 5 名人员。
我想使用 sqlalchemy,events
因为如果我可以让它工作,它将在以后派上用场用于其他自动化。
我正在关注 Miguel Grinberg 先生关于如何制作烧瓶应用程序和定义我的模型(db.Model not Base)的教程。
我读到要使用@event.listens_for(User.__table__, "after_insert")
我必须使用声明性基础。有没有解决的办法?我的模型结构涉及近 15 个表!
class User(db.Model):
__tablename__ = "user"
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
email = db.Column(db.String(64), unique=True, index=True)
username = db.Column(db.String(64), unique=True, index=True)
password_hash = db.Column(db.String(128))
store = db.relationship('Store', uselist=False, backref="user")
@event.listens_for(User.__table__, "after_insert")
def add_personnel(*args, **kwargs):
for i in range(5):
db.session.add(Personnel,store_id = User.query.last().id)
db.session.commit()
return None
class Personnel(db.Model):
__tablename__ = "personnel"
id = db.Column(db.Integer, primary_key=True)
store_id = db.Column(db.Integer, db.ForeignKey('store.id'))
first_name …
Run Code Online (Sandbox Code Playgroud)