多线程python psycopg2

时间:2018-02-05 19:56:00

标签: python multithreading postgresql psycopg2

我在python中的程序中使用多线程。我有3个队列。在其中一个我正在向postgres数据库插入数据。但之前,我需要检查数据库中是否已存在具有特定域名的行。所以我得到了:

let selectedStar = UIImage(named:"004-star-selected.png")
let star = UIImage(named: "001-star.png")
@IBAction func rating(_ sender: UIButton) {
    DispatchQueue.main.async {
        let tag = sender.tag
        for i in 10...14{
            let view = self.view.viewWithTag(i) as! UIButton
            if i <= tag{
                view.setImage(self.selectedStar, for: UIControlState.normal)
            }else{
                view.setImage(self.star, for: .normal)
            }
        }
    }
}

这是我的第三个队列的代码的一部分。我在这里连接到数据库(在main()函数中):

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)

当我运行我的脚本时,我得到了:

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()

为什么其中一些我收到错误?

1 个答案:

答案 0 :(得分:0)

这可能与所有线程共享相同连接和游标的事实有关。我可以想象一个案例cur.execute()被运行,然后cur.fetchone()被另一个线程运行,然后cur.fetchone()再次被(又一个或相同或前一个)线程运行,没有{{1}介于两者之间。 Python GIL将在每行线程(语句)之间切换。因此,第二次运行cur.execute时,就没有结果了:最初只能获取一行,现在已经用完了。
您可能希望隔离每个游标,或以某种方式使fetchone()命令成为原子。

问题are transactions in postgresql via psycopg2 per cursor or per connection(DBA StackExchange链接)的答案提到了每个连接的事务,因此隔离游标可能对您没有帮助。