为什么flask-sqlalchemy不写更改

时间:2019-07-25 10:04:16

标签: python sqlalchemy

在某些情况下,对对象本身所做的更改不会更改数据库: 具有以下models.py代码:

class Task(db.Model):
    __tablename__ = "task"
    __table_args__ = {'autoload': True,
                      'autoload_with': db.engine}

    [...]

    def action(self, action_type):
        if self.task_type == 1:
            if action_type == 1:
                try:
                    user = User.query.filter(User.n_login == self.requestor).first()
                    role_id = self.value
                    new_user_to_role = UserToRole(user.id, role_id)
                    db.session().add(new_user_to_role)
                    db.session().commit() # HERE WE FACE EXCEPTION INTEGRITYERROR IF ROLE IS ALREADY ASSIGNED
                    self.status = 1
                except IntegrityError as ex:
                    # Already assigned role
                    if "UNIQUE constraint" in ex.args[0]:
                        print("Role was already assigned.")
                        db.session().rollback()
                        self.status = 1
                    else:
                        raise IntegrityError(ex.statement, ex.params, ex.orig)

                except Exception as ex:
                    print(ex)
                    self.status = 999
                    db.session().rollback()
                finally:
                    self.update_timestamp = current_timestamp

当我遇到用户尝试分配已经分配的角色的场景时,我收到IntegrityError异常,并且正在处理要回滚更改,然后设置self.status = 1的原因,因为该任务即使角色是先前分配的,也可以完成。但是状态只有在页面上可见,直到刷新。

有时在调试模式下,我收到以下错误:

sqlalchemy.exc.ProgrammingError: (raised as a result of Query-invoked autoflush; consider using a session.no_autoflush block if this flush is occurring prematurely) (sqlite3.ProgrammingError) SQLite objects created in a thread can only be used in that same thread.The object was created in thread id 10720 and this is thread id 13540 (Background on this error at: http://sqlalche.me/e/f405)

但是只有当我在调试模式下缓慢按下F8时,它才会发生;如果我快速按下它,则不会发生。

有人知道为什么不写变更吗?

1 个答案:

答案 0 :(得分:0)

我想这就像调试模式所说的那样-sqlalchemy在进行新查询之前先刷新您的更改,如in sqlalchemy docs所述:
All changes to objects maintained by a Session are tracked - before the database is queried again or before the current transaction is committed, it flushes all pending changes to the database. This is known as the Unit of Work pattern.

设置db.session().commit()后,您可以通过self.status将更改保存到数据库中