问题描述
比如我想在 User 对象成功 session.commit() 之后创建一个 Wallet 对象,Wallet 对象创建成功之后可能又需要创建另一个对象。用函数把创建多个对象的代码封装起来这种方式我不想用,因为 User 对象可能不是在代码中显式创建的,有时是通过 load fixtures 的方式(我搞了个类似 django 的 load fixtures 功能)创建的。
尝试过的方法
我试着利用 flask-sqlalchemy 的 models_committed 信号来做触发,比如这样:
@models_committed.connect_via(app)
def on_models_committed(sender, changes):
for obj, change in changes:
if change == 'insert' and hasattr(obj, '__commit_insert__'):
obj.__commit_insert__()
elif change == 'update' and hasattr(obj, '__commit_update__'):
obj.__commit_update__()
elif change == 'delete' and hasattr(obj, '__commit_delete__'):
obj.__commit_delete__()
然后在 User model 中添加 commit_insert 方法,在该方法中创建 Wallet 对象,比如这样:
def __commit_insert__(self):
wallet = Wallet(name="my_wallet")
db.session.add(wallet)
db.session.commit()
实际看到的错误信息又是什么?
然而,在创建 Wallet 对象 commit 的时候,报了这么个错误:
This session is in 'committed' state; no further SQL can be emitted within this transaction.
讲道理,临时搞搞 flask 还没倒出功夫缕源码看看 flask-sqlalchemy 怎么个逻辑,所以先问一下大家,看看有没有遇到过这种情况,类似的场景在 flask 中是否有什么通用的处理方式?
另外,
我是有去 stack-overflow 上先看一眼的,结果这个答案讲道理挺尴尬的.
这个问题可以通过直接执行 sql 语句来搞
参考了 @低默 给的答案,虽然也会报错,但他的这种 sqlalchemy event 写法很方便获取到 connection 对象,而我原问题中写的 Flask Signaling 方式中如果想获得 connection 需要这样写:
另外还有个问题需要注意就是如果需要执行多个 sql 语句,注意使用事务,例如:
参考链接