Python SQLAlchemy after_insert 映射事件
我刚接触SQLAlchemy,想在创建一个新的用户对象后,默认也创建一个权限对象。看文档说我应该使用after_insert这个事件监听器。问题是,这个事件在对象真正被保存之前就被调用了。
有没有办法让权限对象至少放在一个事务里,或者在用户对象真正保存后再创建的对象列表中呢?
class Users():
__tablename__ = 'users'
user_id = Column(String(36), primary_key=True, nullable=False)
class Permissions():
__tablename__ = 'permissions'
user_id = Column(String(36), ForeignKey('users.user_id'), primary_key=True,
nullable=False)
@event.listens_for(Users, "after_insert")
def create_permissions(mapper, connection, user):
connection.execute(Permissions.__table__.insert(user_id=user.user_id))
出现了一个错误:IntegrityError: (IntegrityError) (1452, '无法添加或更新子行:外键约束失败')
理想情况下,我希望在用户表上不使用数据库触发器来实现这个功能。
2 个回答
4
你不需要把会话(session)附加到ORM对象上。只需像下面这样使用sqlalchemy.orm模块中的object_session函数:
from sqlalchemy.orm import object_session
@event.listens_for(Users, 'after_insert')
def create_permissions(mapper, connection, user):
object_session(user).add(Permissions(user_id=user.user_id))
1
通过调整我的类定义,并把会话对象(session object)附加到每个类上,我可以在插入操作完成后添加一个新的权限对象(Permissions object)。这样,正确的提交顺序就能顺利进行。
class Users():
__tablename__ = 'users'
user_id = Column(String(36), primary_key=True, nullable=False)
............
class Permissions():
__tablename__ = 'permissions'
user_id = Column(String(36), ForeignKey('users.user_id'), primary_key=True,
nullable=False)
............
@event.listens_for(Users, "after_insert")
def create_permissions(mapper, connection, user):
user.session.add(Permissions(user_id=user.user_id))