我在 python 程序中使用多线程。我有3个队列。在其中之一中,我将数据插入 postgres 数据库。但在此之前,我需要检查数据库中是否已存在具有特定域名的行。所以我有:
class AnotherThread(threading.Thread):
def __init__(self, another_queue):
threading.Thread.__init__(self)
self.another_queue = another_queue
def run(self):
while True:
chunk = self.another_queue.get()
if chunk is not '':
dane = chunk[0].split(',',2)
cur.execute("SELECT exists(SELECT 1 FROM global where domain = %s ) ", (domena,))
jest = cur.fetchone()
print(jest)
这是我的第三个队列的代码的一部分。我在这里连接到数据库(在 main() 函数中):
queue = Queue.Queue()
out_queue = Queue.Queue()
another_queue = Queue.Queue()
for i in range(50):
t = ThreadUrl(queue, out_queue)
t.setDaemon(True)
t.start()
for host in hosts:
queue.put(host)
for i in range(50):
dt = DatamineThread(out_queue,another_queue)
dt.setDaemon(True)
dt.start()
conn_str = "dbname='{db}' user='user' host='localhost' password='pass'"
conn = psycopg2.connect(conn_str.format(db='test'))
conn.autocommit = True
cur = conn.cursor()
for i in range(50):
dt = AnotherThread(another_queue)
dt.setDaemon(True)
dt.start()
queue.join()
out_queue.join()
another_queue.join()
cur.close()
conn.close()
当我运行脚本时,我得到:
(False,)
(False,)
(False,)
(False,)
(False,)
(False,)
(False,)
(False,)
(False,)
Exception in thread Thread-128:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner
self.run()
File "domains.py", line 242, in run
jest = cur.fetchone()
ProgrammingError: no results to fetch
Exception in thread Thread-127:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner
self.run()
File "domains.py", line 242, in run
jest = cur.fetchone()
ProgrammingError: no results to fetch
(False,)
(False,)
(False,)
为什么对于其中一些我会收到错误?
最佳答案
这可能与所有线程共享相同的连接和游标有关。我可以想象一个情况 cur.execute()
运行,然后cur.fetchone()
通过另一个线程,然后 cur.fetchone()
再次通过(另一个或相同或上一个)线程,没有 cur.execute
之间。 Python GIL 将在每行(语句)的线程之间切换。因此,第二次fetchone()
运行后,不再有任何结果:最初只有一行要获取,现在已经耗尽。
您可能想要隔离每个光标,或者以某种方式使 cur.execute(...); cur.fetchone()
命令原子。
问题的答案are transactions in postgresql via psycopg2 per cursor or per connection (DBA StackExchange 链接)提到事务是按连接进行的,因此隔离游标可能对您没有帮助。
关于python - 多线程 python psycopg2,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48630476/