【问题标题】:Having issues doing fast enough db inserts inside a Flask endpoint在 Flask 端点内进行足够快的数据库插入时遇到问题
【发布时间】:2019-08-14 20:28:15
【问题描述】:

我在 Flask 中有一个 HTTP POST 端点,它需要将任何数据插入到数据库中。该端点每秒最多可以接收数百个请求。每次有新请求到来时进行插入需要太多时间。我认为每 1000 个请求对所有先前的 1000 个请求数据进行一次批量插入应该像某种缓存机制一样工作。我尝试将 1000 个传入数据对象保存到某个集合中,然后在数组“满”后进行批量插入。

目前我的代码如下所示:

@app.route('/user', methods=['POST'])
def add_user():
    firstname = request.json['firstname']
    lastname = request.json['lastname']
    email = request.json['email']

    usr = User(firstname, lastname, email)

    global bulk
    bulk.append(usr)
    if len(bulk) > 1000:
        bulk = []
        db.session.bulk_save_objects(bulk)
        db.session.commit()

    return user_schema.jsonify(usr)

我遇到的问题是数据库被“锁定”了,我真的不知道这是一个很好的解决方案,但实施得很差,还是一个愚蠢的想法。

sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) database is locked

【问题讨论】:

    标签: python sql api flask sqlalchemy


    【解决方案1】:

    您的错误消息表明您正在使用带有 SQLAlchemy 的 sqlite DB。您可能想尝试更改 sqlite“同步”标志的设置以关闭同步。这可以显着加快 INSERT 查询,但它确实会增加数据丢失的风险。详情请见https://sqlite.org/pragma.html#pragma_synchronous

    在同步关闭 (0) 的情况下,SQLite 继续不同步,只要 它已将数据移交给操作系统。如果申请 运行 SQLite 崩溃,数据将是安全的,但数据库可能 如果操作系统崩溃或计算机丢失,则会损坏 在将数据写入磁盘表面之前上电。在 另一方面,同步的提交可以快几个数量级 关闭

    如果您的应用程序和用例可以承受增加的风险,那么禁用同步可能会消除对批量插入的需求。

    请参阅“如何使用 SQLAlchemy 设置 SQLite PRAGMA 语句”:How to set SQLite PRAGMA statements with SQLAlchemy

    【讨论】:

      【解决方案2】:

      一旦我将代码移到 AWS 上并使用 Aurora 实例作为数据库,问题就消失了,因此我认为可以肯定地得出结论,该问题仅与我的 sqlite3 实例有关。

      最终的解决方案给了我满意的结果,我最终只改变了这一行:

      db.session.bulk_save_objects(批量)

      到这里:

      db.session.save_all(批量)

      我现在可以安全地在该特定端点上每秒执行多达 400 次或更多(尚未测试更多)调用,所有调用均以有效插入结束。

      【讨论】:

        【解决方案3】:

        不是这方面的专家,但似乎数据库已达到其并发限制。您可以尝试使用 Pony 以获得更好的并发和事务管理

        https://docs.ponyorm.org/transactions.html

        默认情况下,Pony 使用乐观并发控制概念来提高性能。有了这个概念,Pony 就不会在数据库行上获取锁。相反,它会验证没有其他事务修改它已读取或正在尝试修改的数据。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-11-19
          • 2014-08-04
          • 1970-01-01
          • 1970-01-01
          • 2016-10-20
          • 1970-01-01
          • 1970-01-01
          • 2012-09-09
          相关资源
          最近更新 更多