python-3.x 如何只回滚最后一个会话,在sqlalchemy中添加操作?

zbwhf8kr  于 2023-08-08  发布在  Python
关注(0)|答案(1)|浏览(116)

我正在创建一个函数,从数据库表User中获取一个特定的用户,如果它不存在,就创建它:

def get_user_id(session, username):
    query = session.query(User).filter(User.username == username)
    try:
        user = query.one()
    except NoResultFound as e:
        user = User(username=username)
        try:
            session.add(user)
            session.flush()
        except IntegrityError as e:
            session.rollback() # ! This will rollback all changes made to the session.
            user = query.one()
    return user.id_user

字符串
如果在事务处理期间创建了相同的用户名,则用户创建部分可能会失败,因为它具有唯一约束。在这种情况下,我将查询现有的id。但是,我需要添加回滚,以便会话在提交时不会引发错误。
我希望能够在同一个会话中多次调用该函数,而无需在调用之间提交。但是,回滚将撤消所有以前添加的用户或在调用该函数之前所做的其他修改。有没有一种方法可以只回滚在当前函数调用中添加的用户?

c7rzv4ha

c7rzv4ha1#

虽然很晚了,但我在一个fastapi项目中遇到了类似的问题

@api.post("/add_objs")
async def bulk_addition(deps): 
    for ip in ip_lst.ips:
        with db.begin_nested() as session:
            try:
                # add new entry in the table and rollback if it is a duplicate one 
                db.add(Obj(foo=foo, bar=bar))
                db.flush()
            except IntegrityError as err:
                session.rollback()
                continue
    db.commit()

字符串
来自@Gord Thompson引用的文档
每次调用Session.开始_nested()时,都会向当前数据库事务范围内的数据库发出一个新的“BEGIN SAVEPOINT”命令(如果尚未进行,则启动一个)。
它会创建一个可用于捕获每个示例错误的保存点

相关问题