在Python中序列化Sqlite3

23 投票
4 回答
11366 浏览
提问于 2025-04-16 19:16

为了充分利用并发,SQLite3允许多个线程以三种方式访问同一个连接:

  1. 单线程模式。在这种模式下,所有的互斥锁都被禁用,所以SQLite在同一时间只能被一个线程使用,这样使用起来就不安全。
  2. 多线程模式。在这种模式下,只要确保同一个数据库连接不会被两个或更多线程同时使用,SQLite就可以安全地被多个线程使用。
  3. 序列化模式。在序列化模式下,SQLite可以被多个线程安全地使用,没有任何限制。

有没有人知道我怎么在Python中把连接设置为序列化模式呢?
Python有一个“check_same_thread”的选项,可以在多线程和单线程之间切换;但是,我找不到怎么把它设置为序列化模式的方法。

4 个回答

1

sqlite的页面 http://www.sqlite.org/threadsafe.html 上说:“默认模式是序列化的。” 你测试过这个吗?发现不是这样吗?

编辑:


如果它无法正常工作,可能是因为ctypes?我不太确定这会不会影响加载的sqlite模块。我猜可能不会,因为我想sqlite3_initialize()这个函数可能是在模块加载时被调用的?或者说只有在你创建数据库对象时才会被调用?

http://www.sqlite.org/c3ref/config.html

>>> import sqlite3
>>> import ctypes
>>> from ctypes.util import find_library
>>> sqlite_lib = ctypes.CDLL(find_library('sqlite3'))
>>> sqlite_lib.sqlite3_config(3) # http://www.sqlite.org/c3ref/c_abort.html
0   # no error....
>>> 
3

我写了一个库来解决这个问题。对我来说很好用。

https://github.com/palantir/sqlite3worker

8

Python的SQLite模块不是线程安全的。这意味着如果你关闭了它的检查功能,你就需要确保所有的代码都是按顺序执行的,包括垃圾回收的部分。(我的APSW模块是线程安全的,并且能正确处理错误信息的线程安全问题。)

不过,在同一个进程中使用多个独立的连接是安全的,我建议你这样做。此外,可以把数据库切换到写前日志模式,这样即使有很多写入操作,你的性能也会很好。

撰写回答