我可以在ORM事件回调中使用SQLAlchemy关系吗?总是得到无

时间:2015-02-23 22:13:12

标签: python sqlalchemy flask-sqlalchemy

我有一个类似于以下内容的用户模型:

class User(db.Model):

    id = db.Column(db.BigInteger, primary_key=True)
    account_id = db.Column(db.BigInteger, db.ForeignKey('account.id'))

    account = db.relationship('Account',
         backref=db.backref('ref_users', cascade='delete'))

    ...

def after_user_write(mapper, connection, target):
    target.account.invalidate_cache()

event.listen(User, 'after_insert', after_user_write)
event.listen(User, 'after_update', after_user_write)
event.listen(User, 'after_delete', after_user_write)

在调用插入after_user_write时,target.accountNone(导致错误),我希望它是一个帐户模型。 target.account_id设置正确,似乎关系参考不能像我期望的那样工作。

关于导致这种情况的任何想法?

2 个答案:

答案 0 :(得分:2)

手动创建对象时,SQLAlchemy不会自动设置关系。如果要在事件回调中访问account,请在创建User实例时设置它:

a1 = Account()
u1 = User(account_id=a1.id)
db.session.add(u1)
db.session.commit()

assert u1.account is None

a2 = Account()
# Here: set the account object, instead of the id
u2 = User(account=a2)
db.session.add(u2)
db.session.commit()

assert u2.account == a2
assert u2.account_id == a2.id

答案 1 :(得分:0)

我找到的最简单的解决方案是使用 Session.enable_relationship_loading() 方法。示例:

def after_user_write(mapper, connection, target):
    db.session().enable_relationship_loading(target)
    target.account.invalidate_cache()  # Account will no longer be None here