python-3.x - 在线程中使用 psycopg2 游标的正确方法是什么?

标签 python-3.x postgresql psycopg2 psql

我觉得我的问题的答案就在这两个 SO 问题中,但我发现答案措辞很差(或高于我的工资等级)

  • multi thread python psycopg2
  • Are transactions in PostgreSQL via psycopg2 per-cursor or per-connection?

  • 问题:使用 psycopg2 确保线程安全的正确方法是什么
    选项 1:每个线程都有自己的游标
    import threading
    import psycopg2
    
    conn = psycopg2.connect (
        host=127.0.0.1,
        user='john',
        password='1234',
        dbname='foo',
        port=1234)
    
    class Foo (threading.Thread):
        def __init__ (self):
            threading.Thread.__init__(self)
    
        def run (self):
            global conn
    
            cur = conn.cursor()
            sql_query="SELECT * from foo;"
            print(cur.execute (sql_query))
            conn.commit()
    
    num_threads = 100
    threads = []
    
    for i in seq (num_threads):
        threads.append (Foo())
    
    for i in seq (num_threads):
        threads[i].start()
    
    for i in seq (num_threads):
        threads[i].join()
    
    选项 2:每个线程都有自己的连接
    import threading
    import psycopg2
    
    db_conn = psycopg2.connect (
        host=127.0.0.1,
        user='john',
        password='1234',
        dbname='foo',
        port=1234)
    
    class Foo (threading.Thread):
        def __init__ (self):
            threading.Thread.__init__(self)
            self.conn = psycopg2.connect (
                host=127.0.0.1,
                user='john',
                password='1234',
                dbname='foo',
                port=1234)
    
        def run (self):
            cur = self.conn.cursor()
            sql_query="SELECT * from foo;"
            print(cur.execute (sql_query))
            conn.commit()
    
    num_threads = 100
    threads = []
    
    for i in seq (num_threads):
        threads.append (Foo())
    
    for i in seq (num_threads):
        threads[i].start()
    
    for i in seq (num_threads):
        threads[i].join()
    

    最佳答案

    每个线程都应该有自己的数据库连接。
    一个 PostgreSQL 连接在给定时间只能处理一个语句(除非您使用的是 server side cursor ,但即使如此,该连接也只能同时处理一个 FETCH)。
    因此,如果多个线程要共享一个数据库连接,则它们必须仔细协调以确保只有一个线程同时使用该连接。例如,当另一个线程仍在等待查询结果时,您不能发送新查询。

    关于python-3.x - 在线程中使用 psycopg2 游标的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64602183/

    相关文章:

    python - 如何检查表中是否存在列,如果不存在则不插入

    ruby-on-rails - 如何在 Ruby on Rails 中将无限日期范围保存到 Postgres?

    python - 如何从调用者访问变量,即使它不是封闭范围(即实现动态范围)?

    python - 将复杂对象打印为多行字符串

    python - 使用 petl 将字符串转换为元组

    postgresql - 如何锁定表以进行写入

    mysql - 使用 MIN() 连接,其中 MIN() 大于连接左侧的值

    python - High Sierra + Python + Postgresql 错误 : Illegal instruction: 4

    python - 为什么 psycopg2 不执行我的任何 SQL 函数? (索引错误 : tuple index out of range)

    django - ForeignKey 与抽象类的关系