python:如何在具有队列的线程之间共享sqlite连接?

2024-09-22 20:27:57 发布

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

我在ArchLinuxx86上使用Python3.2.1。
我试图用类似于以下的代码在线程化的定时循环中更新sqlite数据库:

import sqlite3
from threading import Timer
from queue import Queue

class DBQueue(Queue):
    def give(self, item):
        self.task_done()
        self.join()
        self.put(item)
        return True


def timer():
    print('A')
    Timer(3, add).start()


def add():
    print('B')
    db = qdb.get()
    cur = db.cursor()
    cur.execute('INSERT INTO Foo (id) VALUES (NULL)')
    qdb.give(db)
    timer()

qdb = DBQueue()
# SOLUTION #1:
# qdb.put(sqlite3.connect(':memory:', check_same_thread=False))
# SOLUTION #2: see Eli Bendersky's answer
qdb.put(sqlite3.connect(':memory:'))
db = qdb.get()
cur = db.cursor()
cur.execute('CREATE TABLE Foo (id INTEGER PRIMARY KEY)')
qdb.give(db)
timer()

不幸的是:

A
B
Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/lib/python3.2/threading.py", line 736, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.2/threading.py", line 942, in run
    self.function(*self.args, **self.kwargs)
  File "/home/dario/dev/python/prova/src/prova4.py", line 27, in add
    cursor = db.cursor()
sqlite3.ProgrammingError: SQLite objects created in a thread can only be used in that same thread.The object was created in thread id 140037302638336 and this is thread id 140037262886656

仅共享一个光标不会产生更好的结果:

conn = sqlite3.connect(':memory:')
qdb.put(conn.cursor())

我很确定我根本不知道如何使用队列在线程之间共享数据库,有人能帮我吗? 谢谢您!


Tags: inimportselfiddbputdefthread
1条回答
网友
1楼 · 发布于 2024-09-22 20:27:57

您不需要Queue-只需使用两个线程到同一个数据库的单独连接。请记住,当单独的连接将数据提交到数据库时,您不应该对排序有太多期望。将其视为程序的两个不同实例同时访问数据库。


如果出于某种原因,您认为您绝对必须共享一个连接,那么请尝试这样做:既然您遇到了从一个线程创建SQLite对象并在另一个线程中使用它们的问题,为什么不将处理db/连接的任务委托给一个线程,并让它通过Queues与其他线程通信。更具体地说:

  • 线程数据库线程:“拥有”连接。从其他线程获取队列中的命令,执行这些命令,将结果放入“结果队列”
  • 线程A、B、C:将“命令”传递到队列中,并从“结果队列”中获取结果。

注意,这些命令不是SQLite对象。

相关问题 更多 >