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中,而不是单独放置时,它正在工作