【发布时间】:2011-07-16 12:04:21
【问题描述】:
我在 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())
我很确定我根本不了解如何使用队列在线程之间共享数据库,有人可以帮助我吗? 谢谢!
【问题讨论】:
-
两分钱:python中不要使用线程,改用多处理,每个进程使用单独的数据库连接。
-
谢谢,我会看看多处理,但是,另请参阅我在 Eli 的回答中的评论,我想避免多个连接,因为我不想提交更改。这种情况真的不能使用队列吗?
-
如果我使用
check_same_thread=False连接到数据库,如果我使用队列会很危险吗? -
我已经测试了
check_same_thread=False方法,它似乎运行良好:对于那些阅读,请确保避免同时使用排队或类似方法访问数据库。
标签: python multithreading sqlite timer queue