【问题标题】:sqlite3.ProgrammingError: SQLite objects created in a thread can only be used in that same thread. In django 2.2sqlite3.ProgrammingError:在线程中创建的 SQLite 对象只能在同一线程中使用。在 django 2.2 中
【发布时间】:2021-01-16 20:42:55
【问题描述】:

我在测试服务器中遇到了这个问题。但不在生产中。我尝试了一些解决方案,例如 python manage.py runserver --noreload 和编辑 /lib/python3.6/site-packages/django/utils/autoreload.py 这个文件。

在文档中提到。

https://github.com/django/django/commit/5bf2c87ece216b00a55a6ec0d6c824c9edabf188

这个错误信息看起来像,

sqlite3.ProgrammingError: 在一个线程中创建的 SQLite 对象只能在同一个线程中使用。该对象是在线程 id 140000522213120 中创建的,这是线程 id 140000744696768。

请建议我解决此问题的解决方案,以前有人遇到过此问题。帮我解决这个问题。

【问题讨论】:

    标签: python-3.x django sqlite


    【解决方案1】:

    这里的问题是 SQLite 必须处理由于多个线程并发访问而引起的冲突,即一个线程创建和访问的 SQLite 数据库不能允许另一个线程访问它。这可能是由以下情况引起的:

    1. 全局连接对象被创建,然后由不同的线程访问
    2. 不同连接之间的连接对象未正确关闭

    始终建议使用 ORM 来处理数据库并有效地管理它们的连接生命周期。对于 Sqlite,使用最广泛的 ORM 是SqlAlchemy。使用 ORM 或许可以解决这个问题。

    但是,对于非常简单的应用程序,使用 ORM 只是一种过度杀伤力,您可以通过允许并发访问来调整与 Sqlite 数据库的连接方式。这可以通过在建立连接时将check_same_thread 参数设置为False 来完成:

    def initDB(self, file_path):
        self.file_path = file_path
        self.cx = sqlite3.connect(file_path, check_same_thread=False)
        self.cx.execute(self.create_table_str)
        self.cx.execute(self.create_detail_table_str)
        print("init the table strucutre successfully")
    

    话虽如此,以这种方式设置 Sqlite 连接是对应用程序而不是数据库上的handle concurrency 负责,用户应确保对数据库的写入操作是序列化的,以避免任何脏写/更新。

    注意:使用 sqlalchemy 时,使用正确的库和代码隔离非常重要。我特别发现这个post 也很有帮助。

    【讨论】:

      猜你喜欢
      • 2018-06-21
      • 2019-10-30
      • 2021-09-20
      • 2020-09-12
      • 2019-10-21
      • 2017-03-01
      • 2016-03-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多