Python Flask db.session.commit()的SQLAlchemy不起作用

Python Flask db.session.commit()的SQLAlchemy不起作用,python,postgresql,flask,sqlalchemy,sql-update,Python,Postgresql,Flask,Sqlalchemy,Sql Update,我遇到了一个类似的问题,因为向数据库插入新记录是可行的,但无法更新 不同之处在于:我没有收到任何错误消息,每次启动应用程序时都会收到db.create_all() 我启动应用程序上下文和数据库: app.config['SQLALCHEMY_DATABASE_URI'] = 'postgres://karolina@127.0.0.1/tests_results' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True db.init_app

我遇到了一个类似的问题,因为向数据库插入新记录是可行的,但无法更新

不同之处在于:我没有收到任何错误消息,每次启动应用程序时都会收到
db.create_all()

  • 我启动应用程序上下文和数据库:

     app.config['SQLALCHEMY_DATABASE_URI'] = 'postgres://karolina@127.0.0.1/tests_results'
     app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
     db.init_app(app)
     app_context = app.app_context()
     DataBaseController.init(app_context)
    编辑:有多个db实例/当前会话的提示可能是它——尽管我真的不知道该怎么做。在我看来,也许除了appcontext,我还应该从app.py传递db-在极度绝望的情况下,我决定将db和appcontext从主应用传递到每个函数-没有结果…至于我现在的操作方式:

    a) 我有一个脚本database.py,它声明了一个“空”db(没有模型):

    c) 最后,我将数据库与我在主应用程序中创建的模型连接起来,并将app_上下文传递给更新数据库中记录的每个线程

    主app.py:

    db.init_app(app)
    app_context = app.app_context()
    DataBaseController.init(app_context, db)
    
    这是我在DataBaseController中启动db的方式:

    @staticmethod
        def update_test_result(app_context):
            with app_context:
                db.session.commit()
    
    from database_management.database import db
    @staticmethod
        def init(app_context, db):
            with app_context:
                db.create_all()
                DataBaseController.create_bots()
                db.session.commit()
    
    @staticmethod 
        def add_result_to_db(db, appcontext, result):
            with appcontext:
                db.session.add(result)
                db.session.commit()
    
    from database_management.database import db
    
    def update_passed_result_in_db(self, db, appcontext, human_said):
            result = DataBaseController.get_test_result(db, appcontext, self.test_id)
            result.result = self.test_passed
            result.status = 'DONE'
            with appcontext:
                db.session.commit()
    
    从主应用程序循环:

    test_cases = TestCasesLoader.split_test_cases(dialog_cases, db, app_context)  # here I create records
        threads_list = list()
        for test_case in test_cases[:10]:
            threads_list.append(Thread(target=test_case.run_test_case, args=(db, app_context, bot_config)))  # and here I update them
    
    创建记录:

    @staticmethod
        def split_test_cases(dialog_cases, db, appcontext):
            db_name = dialog_cases.get("bot_name")
            for test_case in dialog_cases.get("test_case_list"):
                test_result = DataBaseController.get_test_result(db, appcontext, test_id)
                if test_result:
                    DataBaseController.clean_result_data_in_db(db, appcontext, test_result)
                else:
                    test_result = {
                        'id': test_id,
                        'status': 'IN_PROGRESS'
                    }
                    test_result = Result(test_result)
                    DataBaseController.add_result_to_db(db, appcontext, test_result)
    
    在DataBaseController中创建:

    @staticmethod
        def update_test_result(app_context):
            with app_context:
                db.session.commit()
    
    from database_management.database import db
    @staticmethod
        def init(app_context, db):
            with app_context:
                db.create_all()
                DataBaseController.create_bots()
                db.session.commit()
    
    @staticmethod 
        def add_result_to_db(db, appcontext, result):
            with appcontext:
                db.session.add(result)
                db.session.commit()
    
    from database_management.database import db
    
    def update_passed_result_in_db(self, db, appcontext, human_said):
            result = DataBaseController.get_test_result(db, appcontext, self.test_id)
            result.result = self.test_passed
            result.status = 'DONE'
            with appcontext:
                db.session.commit()
    
    在线程中更新:

    def update_passed_result_in_db(self, appcontext):
        print("passed")
        result = DataBaseController.get_test_result(appcontext, self.test_id)
        result.result = self.test_passed
        result.status = 'DONE'
        with appcontext:
            db.session.commit()
    
    这就是DataBaseController中的更新:

    @staticmethod
        def update_test_result(app_context):
            with app_context:
                db.session.commit()
    
    from database_management.database import db
    @staticmethod
        def init(app_context, db):
            with app_context:
                db.create_all()
                DataBaseController.create_bots()
                db.session.commit()
    
    @staticmethod 
        def add_result_to_db(db, appcontext, result):
            with appcontext:
                db.session.add(result)
                db.session.commit()
    
    from database_management.database import db
    
    def update_passed_result_in_db(self, db, appcontext, human_said):
            result = DataBaseController.get_test_result(db, appcontext, self.test_id)
            result.result = self.test_passed
            result.status = 'DONE'
            with appcontext:
                db.session.commit()
    
    如果你知道我可能做错了什么,请告诉我。 非常有趣的是,当我这样做的时候:

    from database_management.database import db
    
    class Result(db.Model):
        id = db.Column(db.String(150), primary_key=True)
        result = db.Column(db.Boolean)
        status = db.Column(db.String(20))
    
    def update_passed_result_in_db(self, db, appcontext):   
    result = DataBaseController.get_test_result(db, appcontext, self.test_id)
            cprint.err(type(result))
            result.id = self.test_id
            result.result = self.test_passed
            result.status = 'working'
            with appcontext:
                db.session.add(result)
                db.session.commit()
    

    记录添加正确…

    问题确实与应用程序上下文有关

    这一个不起作用:

    result = db.session.query(Result).filter_by(id=test_id).first()
    result.id = self.test_id
    result.result = self.test_passed
    result.status = 'working'
    with appcontext:
        db.session.commit()
    
    这一个做到了:

    result_data = {
        'status': 'working'
    }
    with appcontext:
        result = Result.query.filter_by(id=self.test_id).update(result_data)
        db.session.commit()
    

    这是因为查询数据和更新数据应该在一个应用程序上下文中完成,而不是单独完成。

    为了缩小可能性,您没有碰巧从Flask SQLA获得多个
    SQLAlchemy
    类的
    db
    实例?也就是说,
    db.session.commit()
    中使用的
    db
    与模型从中继承的
    db.Model
    相同。您确定
    get\u rest\u result
    中的对象是当前会话的一部分吗?因为我远不能肯定这一点。@IljaEverilä我想你是对的-你能看看我问题中以“编辑”开头的部分吗?@KenKinder我想你是对的-你能看看我问题中以“编辑”开头的部分吗?运行
    .update()
    或多或少跳过ORM。它相当于运行原始SQL。我相信你的治疗还是有问题。如果我是你,我会尝试将整个更新放在一个应用程序上下文中,尽管我不确定这是问题所在。或者,如果您有一个可以测试的应用程序的简短示例,这可能会奏效。@KenKinder您说得对。当我对结果进行查询,然后对其进行更改并将其放在一个appcontext中,而不是单独放置时,它正在工作