SqlAlchmey根据其他行值向表中添加新行

时间:2020-02-09 14:53:10

标签: python sql flask sqlalchemy flask-sqlalchemy

在以下代码中,如果表中存在以下行,我将尝试向TransferRequest表添加新行:

1- partnerId列的值与我​​的预期相同

2-并且此行的状态现在为open

并且在插入后,我想将过滤后的行的状态更改为booked

        partner = db.session.query(TransferRequest).filter(TransferRequest.id == partner_id).one()
        if partner.status == RequestStatus.open.value:
            request = TransferRequest()
            #set values

            db.session.add(request)
            db.session.commit()

            db.session.query(TransferRequest). \
                filter(TransferRequest.id == partner_id). \
                update({"status": RequestStatus.booked.value,
                        "partnerId": request.id})
            db.session.commit()

            return "success"
        else:
            return "failure"

这里的问题是,当我查询具有特定ID的项目并检查其状态时,在达到if条件后,其他人可能会将行的状态从open更改为booked。在这种情况下,我不能插入行,插入后也不能执行update命令。

我正在寻找一种可以在事务中执行所有这3个查询的方法,以便所有数据情况从第一条语句到结束语句都锁定。 (或者当然可以解决此问题的任何其他解决方案)

1 个答案:

答案 0 :(得分:1)

我认为您代码中的主要问题是两次使用commit()。它将所有内容提交到数据库(作为事务),然后释放基础的事务锁。第二件事是,我还应该将with_for_update()添加到您的选择查询中,以锁定特定的行。完成一次提交,以保留您的更改并释放锁。一个例子可能是:

    session = sessionmaker(bind=engine, autocommit=False)

    partner = session.query(TransferRequest).with_for_update().filter(TransferRequest.id == partner_id).one()
    if partner.status == RequestStatus.open.value:
        request = TransferRequest()
        #set values

        session.add(request)
        session.flush()

        session.query(TransferRequest). \
            filter(TransferRequest.id == partner_id). \
            update({"status": RequestStatus.booked.value,
                    "partnerId": request.id})
        session.commit()

        return "success"
    else:
        return "failure"