我正在尝试通过将重复用户登录到另一个表来在插入中的主键冲突后恢复。但是,我的代码会产生错误InvalidRequestError: This transaction is inactive
。
不幸的是,回溯并未显示此函数中发生错误的特定行 - 它只会与调用此函数的函数一样深(这很奇怪)。
我的try / except开始/回滚/提交模式看起来是否正确?
def convert_email(db, user_id, response):
"""Map a submitted email address to a user, if the user
does not yet have an email address.
"""
email = response['text_response']
trans = db.begin()
try:
update_stmt = users_tbl.update(
and_(users_tbl.c.user_id==user_id,
users_tbl.c.email==None))
db.execute(update_stmt.values(dict(email=email)))
trans.commit()
except sqlalchemy.exc.IntegrityError as e:
trans.rollback()
if e.orig.pgcode == UNIQUE_VIOLATION:
trans = db.begin()
try:
user = db.execute(users_tbl.select(users_tbl.c.email==email))
parent_user_id = user.first()['user_id']
insert_stmt = duplicate_public_users_tbl.insert().values(
user_id=user_id,
parent_id=parent_user_id)
db.execute(insert_stmt)
trans.commit()
except sqlalchemy.exc.IntegrityError as e:
trans.rollback()
if e.orig.pgcode != UNIQUE_VIOLATION:
raise
答案 0 :(得分:1)
调用函数正在生成异常,调用函数本身包含在事务中。
with engine.begin() as db:
convert_email(db, user_id, response)
内部rollback()
调用也必须终止外部事务。 Transaction.close()
,
...这用于取消交易而不影响封闭交易的范围。