同时从多个请求更新同一数据库对象

2024-10-03 02:32:07 发布

您现在位置:Python中文网/ 问答频道 /正文

我现在遇到了烧瓶和烧瓶炼金术的问题

我有一些线程正在运行做一些工作。完成后,他们会将更新发布到我创建的路线上。 更新只是带有文件路径的普通字符串。此字符串应以键和文件路径作为值保存在字典中

我的模型:

class Variant(db.Model):
   id = db.Column(db.Integer, primary_key=True)
   name = db.Column(db.String, nullable=False)
   description = db.Column(db.String)
   dynamic_data = db.Column(MutableDict.as_mutable(PickleType), default={})
   plugins = db.Column(MutableList.as_mutable(PickleType), default=[])  # list saved as Json
   bdf_files = db.Column(MutableDict.as_mutable(PickleType), default={})  # dict of Plugins with Bdf_file
   project_id = db.Column(db.Integer, db.ForeignKey('project.id'), nullable=False)
   deleted = db.Column(db.Boolean, nullable=False)
   base_variant_name = db.Column(db.Integer, nullable=True)code here

我有多个请求同时结束,每个请求都希望向bdf_文件添加一个密钥。我使用PickleType,因此在获取/保存数据时不必解析/加载json

我将数据保存到dict的路径。我添加了一些调试,以准确测试其工作时间和失败时间

@app.route("/update_database_objects", methods=['POST'])
def update_database_objects():
    """
    Not yet syncronized way to update Database from multiple Threads.
    :return: HTML Success
    """
    request_json = request.get_json()
    if request_json["model_data"] == "variant_bdf_files":
        variant_object = Variant.query.filter_by(project_id=request_json["project_id"],
                                                 name=request_json["variant_name"]).first()
        print(f'Now updateing Variant:{request_json["variant_name"]} in Project ID:{request_json["project_id"]}\n'
              f' Key:{request_json["bdf_file_key"]} Value:{request_json["bdf_file_name"]}')
        print("File before edit contains:")
        print("\n".join(variant_object.bdf_files))
        variant_object.bdf_files[request_json["bdf_file_key"]] = request_json["bdf_file_name"]
        print("File after contains:")
        print("\n".join(variant_object.bdf_files))
        db.session.commit()
        print("File after database Commit contains:")
        print("\n".join(variant_object.bdf_files))
        return json.dumps({'success': True}), 200, {'ContentType': 'application/json'}

当我以default threaded=True启动flask服务器时,并不是所有的数据库更新都正确提交,因为有些更新是从旧的过时版本开始的。Threaded=False确实有效,但我不希望更新时服务器没有响应

我正在使用一个sqlite数据库,启动Flask SQLAlchemy v2.4.4,使用Flask v1.1.2

app.config['SQLALCHEMY_DATABASE_URI'] = f"sqlite:///{DATABASE_PATH}"
db = SQLAlchemy(app)

会话应该确定范围,并通过请求和Alchemy来防止此问题,还是不应该

以下是我使用threaded=True尝试并失败的内容。 我尝试直接在线程中访问数据库。 我尝试使用“with app.app_context():”在线程中直接访问数据库 我尝试在线程内创建会话对象,并在之后删除它们

我现在的问题是:如何确保多个请求不会用Flask SQLAlchemy覆盖数据?我可以强制合并吗

下面是一些示例日志来说明这个问题。在它们中,每个新请求都应该有一个附加行。最后,字典里应该有8个键。有时我只有两个-(

希望有人能帮助我! 非常感谢。:-)

2021-04-22 17:39:42 eveci068 werkzeug[18966] INFO 127.0.0.1 - - [22/Apr/2021 17:39:42] "GET /process_status HTTP/1.1" 200 -
Now updateing Variant:30 in Project ID:1
 Key:Model_Assembly.assembly_rollgeraeusch_animation Value:/home/xxx/.ASPT/Projects/Test1/30/Standardrechnungen/Test1_Rollgeraeusch_Animation_30_20210422-173943.bdf
File before edit contains:
File after contains:
Model_Assembly.assembly_rollgeraeusch_animation
Now updateing Variant:30 in Project ID:1
 Key:Model_Assembly.assembly_akustische_empfindlichkeiten_rg Value:/home/xxx/.ASPT/Projects/Test1/30/Standardrechnungen/Test1_Empfindlichkeiten_rg_30_20210422-173943.bdf
File before edit contains:
File after contains:
Model_Assembly.assembly_akustische_empfindlichkeiten_rg
File after database Commit contains:
2021-04-22 17:39:43 eveci068 werkzeug[18966] INFO 127.0.0.1 - - [22/Apr/2021 17:39:43] "POST /update_database_objects HTTP/1.1" 200 -
2021-04-22 17:39:43 eveci068 apscheduler.executors.default[18966] INFO Job "152 (trigger: date[2021-04-22 17:39:38 CEST], next run at: 2021-04-22 17:39:38 CEST)" executed successfully
2021-04-22 17:39:43 eveci068 aspt_web.run[18966] INFO Job: 152 finished!
2021-04-22 17:39:43 eveci068 aspt_web.run[18966] INFO Return Value: {'bdf_file_name': '/home/xxx/.ASPT/Projects/Test1/30/Standardrechnungen/Test1_Rollgeraeusch_Animation_30_20210422-173943.bdf'}
Model_Assembly.assembly_rollgeraeusch_animation
Response from Rollgeraeusche Animation Post: <Response [200]>
2021-04-22 17:39:44 eveci068 werkzeug[18966] INFO 127.0.0.1 - - [22/Apr/2021 17:39:44] "POST /update_database_objects HTTP/1.1" 200 -
2021-04-22 17:39:44 eveci068 aspt_web.run[18966] INFO Response from Job_Error Post: <Response [200]>
File after database Commit contains:
Model_Assembly.assembly_akustische_empfindlichkeiten_rg
Now updateing Variant:30 in Project ID:1
 Key:Model_Assembly.assembly_akustische_empfindlichkeiten_mg Value:/home/xxx/.ASPT/Projects/Test1/30/Standardrechnungen/Test1_Empfindlichkeiten_mg_30_20210422-173944.bdf
File before edit contains:
Model_Assembly.assembly_akustische_empfindlichkeiten_rg
File after contains:
Model_Assembly.assembly_akustische_empfindlichkeiten_rg
Model_Assembly.assembly_akustische_empfindlichkeiten_mg
Response from Akustische Empfindlichkeiten_RG Post: <Response [200]>
2021-04-22 17:39:44 eveci068 werkzeug[18966] INFO 127.0.0.1 - - [22/Apr/2021 17:39:44] "POST /update_database_objects HTTP/1.1" 200 -
2021-04-22 17:39:44 eveci068 apscheduler.executors.default[18966] INFO Job "148 (trigger: date[2021-04-22 17:39:38 CEST], next run at: 2021-04-22 17:39:38 CEST)" executed successfully
2021-04-22 17:39:44 eveci068 aspt_web.run[18966] INFO Job: 148 finished!
2021-04-22 17:39:44 eveci068 aspt_web.run[18966] INFO Return Value: {'bdf_file_name': '/home/xxx/.ASPT/Projects/Test1/30/Standardrechnungen/Test1_Empfindlichkeiten_rg_30_20210422-173943.bdf'}
File after database Commit contains:
Model_Assembly.assembly_akustische_empfindlichkeiten_rg
Model_Assembly.assembly_akustische_empfindlichkeiten_mg
Response from Akustische Empfindlichkeiten_MG Post: <Response [200]>
2021-04-22 17:39:44 eveci068 werkzeug[18966] INFO 127.0.0.1 - - [22/Apr/2021 17:39:44] "POST /update_database_objects HTTP/1.1" 200 -
2021-04-22 17:39:44 eveci068 apscheduler.executors.default[18966] INFO Job "147 (trigger: date[2021-04-22 17:39:38 CEST], next run at: 2021-04-22 17:39:38 CEST)" executed successfully
2021-04-22 17:39:44 eveci068 aspt_web.run[18966] INFO Job: 147 finished!
2021-04-22 17:39:44 eveci068 aspt_web.run[18966] INFO Return Value: {'bdf_file_name': '/home/xxx/.ASPT/Projects/Test1/30/Standardrechnungen/Test1_Empfindlichkeiten_mg_30_20210422-173944.bdf'}
2021-04-22 17:39:45 eveci068 werkzeug[18966] INFO 127.0.0.1 - - [22/Apr/2021 17:39:45] "POST /update_database_objects HTTP/1.1" 200 -
2021-04-22 17:39:45 eveci068 aspt_web.run[18966] INFO Response from Job_Error Post: <Response [200]>
Now updateing Variant:30 in Project ID:1
 Key:Model_Assembly.assembly_wellige_teerstrasse_animation Value:/home/xxx/.ASPT/Projects/Test1/30/Standardrechnungen/Test1_WT_Animation_30_20210422-173944.bdf
File before edit contains:
Model_Assembly.assembly_akustische_empfindlichkeiten_rg
Model_Assembly.assembly_akustische_empfindlichkeiten_mg
File after contains:
Model_Assembly.assembly_akustische_empfindlichkeiten_rg
Model_Assembly.assembly_akustische_empfindlichkeiten_mg
Model_Assembly.assembly_wellige_teerstrasse_animation
Now updateing Variant:30 in Project ID:1
 Key:Model_Assembly.assembly_wellige_teerstrasse Value:/home/xxx/.ASPT/Projects/Test1/30/Standardrechnungen/Test1_WelligeTeerstrasse_30_20210422-173944.bdf
File before edit contains:
Model_Assembly.assembly_akustische_empfindlichkeiten_rg
Model_Assembly.assembly_akustische_empfindlichkeiten_mg
File after contains:
Model_Assembly.assembly_akustische_empfindlichkeiten_rg
Model_Assembly.assembly_akustische_empfindlichkeiten_mg
Model_Assembly.assembly_wellige_teerstrasse
2021-04-22 17:39:46 eveci068 werkzeug[18966] INFO 127.0.0.1 - - [22/Apr/2021 17:39:46] "POST /update_database_objects HTTP/1.1" 200 -
2021-04-22 17:39:46 eveci068 aspt_web.run[18966] INFO Response from Job_Error Post: <Response [200]>
Now updateing Variant:30 in Project ID:1
 Key:Model_Assembly.assembly_motorgeraeusch Value:/home/xxx/.ASPT/Projects/Test1/30/Standardrechnungen/Test1_Motorgeraeusch_30_20210422-173945.bdf
File before edit contains:
Model_Assembly.assembly_akustische_empfindlichkeiten_rg
Model_Assembly.assembly_akustische_empfindlichkeiten_mg
File after contains:
Model_Assembly.assembly_akustische_empfindlichkeiten_rg
Model_Assembly.assembly_akustische_empfindlichkeiten_mg
Model_Assembly.assembly_motorgeraeusch
File after database Commit contains:
Model_Assembly.assembly_akustische_empfindlichkeiten_rg
Model_Assembly.assembly_akustische_empfindlichkeiten_mg
Model_Assembly.assembly_motorgeraeusch
Response from Motorgeraeusche Post: <Response [200]>
2021-04-22 17:39:46 eveci068 werkzeug[18966] INFO 127.0.0.1 - - [22/Apr/2021 17:39:46] "POST /update_database_objects HTTP/1.1" 200 -
2021-04-22 17:39:46 eveci068 apscheduler.executors.default[18966] INFO Job "150 (trigger: date[2021-04-22 17:39:38 CEST], next run at: 2021-04-22 17:39:38 CEST)" executed successfully
2021-04-22 17:39:46 eveci068 aspt_web.run[18966] INFO Job: 150 finished!
2021-04-22 17:39:46 eveci068 aspt_web.run[18966] INFO Return Value: {'bdf_file_name': '/home/xxx/.ASPT/Projects/Test1/30/Standardrechnungen/Test1_Motorgeraeusch_30_20210422-173945.bdf'}
Now updateing Variant:30 in Project ID:1
 Key:Model_Assembly.assembly_rollgeraeusch Value:/home/xxx/.ASPT/Projects/Test1/30/Standardrechnungen/Test1_Rollgeraeusch_30_20210422-173946.bdf
File before edit contains:
Model_Assembly.assembly_akustische_empfindlichkeiten_rg
Model_Assembly.assembly_akustische_empfindlichkeiten_mg
Model_Assembly.assembly_motorgeraeusch
File after contains:
Model_Assembly.assembly_akustische_empfindlichkeiten_rg
Model_Assembly.assembly_akustische_empfindlichkeiten_mg
Model_Assembly.assembly_motorgeraeusch
Model_Assembly.assembly_rollgeraeusch
2021-04-22 17:39:46 eveci068 werkzeug[18966] INFO 127.0.0.1 - - [22/Apr/2021 17:39:46] "POST /update_database_objects HTTP/1.1" 200 -
2021-04-22 17:39:46 eveci068 aspt_web.run[18966] INFO Response from Job_Error Post: <Response [200]>
File after database Commit contains:
Model_Assembly.assembly_akustische_empfindlichkeiten_rg
Model_Assembly.assembly_akustische_empfindlichkeiten_mg
Model_Assembly.assembly_wellige_teerstrasse
Response from Wellige Teerstraße Post: <Response [200]>
2021-04-22 17:39:47 eveci068 werkzeug[18966] INFO 127.0.0.1 - - [22/Apr/2021 17:39:47] "POST /update_database_objects HTTP/1.1" 200 -
2021-04-22 17:39:47 eveci068 apscheduler.executors.default[18966] INFO Job "153 (trigger: date[2021-04-22 17:39:38 CEST], next run at: 2021-04-22 17:39:38 CEST)" executed successfully
2021-04-22 17:39:47 eveci068 aspt_web.run[18966] INFO Job: 153 finished!
2021-04-22 17:39:47 eveci068 aspt_web.run[18966] INFO Return Value: {'bdf_file_name': '/home/xxx/.ASPT/Projects/Test1/30/Standardrechnungen/Test1_WelligeTeerstrasse_30_20210422-173944.bdf'}
2021-04-22 17:39:47 eveci068 werkzeug[18966] INFO 127.0.0.1 - - [22/Apr/2021 17:39:47] "POST /update_database_objects HTTP/1.1" 200 -
2021-04-22 17:39:47 eveci068 aspt_web.run[18966] INFO Response from Job_Error Post: <Response [200]>
Now updateing Variant:30 in Project ID:1
 Key:Model_Assembly.assembly_leerlauf Value:/home/xxx/.ASPT/Projects/Test1/30/Standardrechnungen/Test1_Leerlauf_30_20210422-173946.bdf
File before edit contains:
Model_Assembly.assembly_akustische_empfindlichkeiten_rg
Model_Assembly.assembly_akustische_empfindlichkeiten_mg
Model_Assembly.assembly_wellige_teerstrasse
File after contains:
Model_Assembly.assembly_akustische_empfindlichkeiten_rg
Model_Assembly.assembly_akustische_empfindlichkeiten_mg
Model_Assembly.assembly_wellige_teerstrasse
Model_Assembly.assembly_leerlauf
File after database Commit contains:
Model_Assembly.assembly_akustische_empfindlichkeiten_rg
Model_Assembly.assembly_akustische_empfindlichkeiten_mg
Model_Assembly.assembly_wellige_teerstrasse_animation
Response from Wellige Teerstraße Animation Post: <Response [200]>
2021-04-22 17:39:47 eveci068 werkzeug[18966] INFO 127.0.0.1 - - [22/Apr/2021 17:39:47] "POST /update_database_objects HTTP/1.1" 200 -
2021-04-22 17:39:47 eveci068 apscheduler.executors.default[18966] INFO Job "154 (trigger: date[2021-04-22 17:39:38 CEST], next run at: 2021-04-22 17:39:38 CEST)" executed successfully
2021-04-22 17:39:47 eveci068 aspt_web.run[18966] INFO Job: 154 finished!
2021-04-22 17:39:47 eveci068 aspt_web.run[18966] INFO Return Value: {'bdf_file_name': '/home/xxx/.ASPT/Projects/Test1/30/Standardrechnungen/Test1_WT_Animation_30_20210422-173944.bdf'}
2021-04-22 17:39:48 eveci068 werkzeug[18966] INFO 127.0.0.1 - - [22/Apr/2021 17:39:48] "POST /update_database_objects HTTP/1.1" 200 -
2021-04-22 17:39:48 eveci068 aspt_web.run[18966] INFO Response from Job_Error Post: <Response [200]>
File after database Commit contains:
2021-04-22 17:39:48 eveci068 werkzeug[18966] INFO 127.0.0.1 - - [22/Apr/2021 17:39:48] "POST /update_database_objects HTTP/1.1" 200 -
2021-04-22 17:39:48 eveci068 apscheduler.executors.default[18966] INFO Job "151 (trigger: date[2021-04-22 17:39:38 CEST], next run at: 2021-04-22 17:39:38 CEST)" executed successfully
2021-04-22 17:39:48 eveci068 aspt_web.run[18966] INFO Job: 151 finished!
2021-04-22 17:39:48 eveci068 aspt_web.run[18966] INFO Return Value: {'bdf_file_name': '/home/xxx/.ASPT/Projects/Test1/30/Standardrechnungen/Test1_Rollgeraeusch_30_20210422-173946.bdf'}
Model_Assembly.assembly_akustische_empfindlichkeiten_rg
Model_Assembly.assembly_akustische_empfindlichkeiten_mg
Model_Assembly.assembly_motorgeraeusch
Model_Assembly.assembly_rollgeraeusch
Response from Rollgeraeusch Post: <Response [200]>
File after database Commit contains:
Model_Assembly.assembly_akustische_empfindlichkeiten_rg
Model_Assembly.assembly_akustische_empfindlichkeiten_mg
Model_Assembly.assembly_wellige_teerstrasse
Model_Assembly.assembly_leerlauf
Response from Leerlauf Post: <Response [200]>

亲切的问候


Tags: runinfomodelresponseassemblydatabasefilerg
1条回答
网友
1楼 · 发布于 2024-10-03 02:32:07

我真的不知道您存储哪些数据的具体细节,但我认为您通常是在问如何在数据库中保持一致性,例如,假设您有一个表“AccountBalances”,account#1有20000美元

然后一次运行10个进程,向该帐户添加1000美元。有许多方法可以编写这些流程:

选项1(坏方法):

  • 读取现有值($20000)计算新值($21000),然后使用新值(set balance = $21,000)向数据库发送更新

问题是,如果所有进程都在同一时间运行,它们将各自读取20000美元作为当前余额,然后您将得到21000美元,而不是预期的30000美元,或者介于两者之间

选择2(更好的方法):

永远不要告诉数据库期望值,只告诉它增量。与其告诉数据库set balance = $21,000,不如告诉它set balance = balance + $1,000,让数据库处理多个请求(您可能需要一个比sqlite更完整的dbms)

选项3(可审计方式):

将数据存储在分类账而不是账户余额中,只存储交易记录:

+$1,000 into account #1 from process #2 on 2021-04-22 @ 13:34
+$1,000 into account #1 from process #1 on 2021-04-22 @ 13:34
+$1,000 into account #1 from process #4 on 2021-04-22 @ 13:35

然后从另一个角度来解决实际的平衡问题

相关问题 更多 >