2016-10-15 78 views
2

我有一個Python 3程序,它基於它們的ID(在Postgres 9.5數據庫的表中)更新大量行。在進程池中共享數據庫連接

我使用多處理來加快處理速度。由於Psycopg的連接不能跨進程共享,因此我爲每行創建連接,然後關閉它。總體而言,多處理速度比單處理速度快(8個CPU速度快5倍)。但是,創建連接很慢:我只想創建幾個連接,並根據需要保持打開狀態。因爲.map()會將ids_list切成許多提交給進程池的塊,是否可以在同一個塊/進程中共享所有ID的數據庫連接?

示例代碼:

from multiprocessing import Pool 
import psycopg2 


def create_db_connection(): 
    conn = psycopg2.connect(database=database, 
          user=user, 
          password=password, 
          host=host) 
    return conn 


def my_function(item_id): 
    conn = create_db_connection() 

    # Other CPU-intensive operations are done here 

    cur = conn.cursor() 
    cur.execute(""" 
     UPDATE table 
     SET 
     my_column = 1 
     WHERE id = %s; 
     """, 
     (item_id,)) 
    cur.close() 
    conn.commit() 


if __name__ == '__main__': 
    ids_list = [] # Long list of ids 

    pool = Pool() # os.cpu_count() processes 
    pool.map(my_function, ids_list) 

感謝您的幫助,您可以提供。

回答

1

您可以使用Pool構造函數的初始化參數。 在初始化函數中設置數據庫連接。也許傳遞連接憑據作爲參數。

看一看文檔:https://docs.python.org/3/library/multiprocessing.html#module-multiprocessing.pool

+0

謝謝,我認爲這將是解決辦法,我只是試着使用一個初始化: '高清worker_initializer()://全球康涅狄格州康涅狄格州// = create_db_connection()' 但是它實際上比初始化器慢了5%(與標準池()相比)!我不明白爲什麼...... –

+0

也許它與在工作進程中重用數據庫連接有關。你可以做一個操作的時間日誌來找出哪個部分比較慢。 –

+0

您的ids_list中是否有重複項,或者您的CPU密集型部分是否使用了您正在編寫的相同行?這些情況中的任何一種都可能導致鎖爭用問題。我假設你在my_function的末尾仍然有提交,你應該這樣做。 –

相關問題