1

我试图通过将重复用户记录到另一个表来在插入中的主键冲突后恢复。但是,我的代码会产生错误InvalidRequestError: This transaction is inactive

不幸的是,回溯没有显示该函数中发生错误的特定行——它只与调用该函数的函数一样深(这很奇怪)。

我的尝试/除了开始/回滚/提交模式看起来正确吗?

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
4

1 回答 1

1

异常是由调用函数产生的,该函数本身被包装在事务中。

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

内部rollback()调用也必须终止外部事务。的文档暗示了这一点Transaction.close()

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

于 2013-03-21T20:08:41.983 回答