gpt4 book ai didi

python:如何在线程与队列之间共享一个sqlite连接?

转载 作者:太空宇宙 更新时间:2023-11-03 11:10:07 31 4
gpt4 key购买 nike

我在 Arch Linux x86_64 上使用 Python 3.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())

我很确定我根本不了解如何使用队列在线程之间共享数据库,有人可以帮助我吗?谢谢!

最佳答案

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


如果出于某种原因你觉得你绝对必须共享一个连接,那么试试这个:既然你遇到了从一个线程创建 SQLite 对象并在另一个线程中使用它们的问题,为什么不委托(delegate)在单个线程中处理数据库/连接的任务,并让它通过 Queues 与其他人通信。更具体地说:

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

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

关于python:如何在线程与队列之间共享一个sqlite连接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6717221/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com