回滚后的SQLAlchemy恢复“此事务处于非活动状态”

时间:2013-03-21 19:57:07

标签: python sqlalchemy

我正在尝试通过将重复用户登录到另一个表来在插入中的主键冲突后恢复。但是,我的代码会产生错误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

1 个答案:

答案 0 :(得分:1)

调用函数正在生成异常,调用函数本身包含在事务中。

with engine.begin() as db:
    convert_email(db, user_id, response)

内部rollback()调用也必须终止外部事务。 Transaction.close()

的文档暗示了这一点
  

...这用于取消交易而不影响封闭交易的范围。