2012-11-21 66 views
0

希望有人能夠幫助,我有一個充滿挑戰的情況,我似乎無法編寫腳本。我的目標是自動將SQL文件加載到PostgreSQL中。Python子進程假脫機過程

我不知道我有多少的SQL文件的文件夾有這麼intially我檢查的文件夾存在,然後遍歷每個文件和使用psql.exe其加載到PostgreSQL的

我當前的代碼看起來像這樣

if os.path.exists("sql1"): 
    for files in os.listdir("sql1"):  
    load1 = subprocess.Popen("psql -d data -U postgres -f sql1\%s" %files) 


if os.path.exists("sql2"): 
    for files in os.listdir("sql2"):  
    load2 = subprocess.Popen("psql -d data -U postgres -f sql2\%s" %files) 

但是,由於它爲文件夾中的每個SQL文件創建子進程以及爲每個文件夾創建更多子進程,因此會對很多子進程進行後臺處理。

如果將其更改爲subprocess.call,它當然會從下一個文件夾加載和阻止加載文件,而不是爲每個文件夾運行一個進程。

有誰知道我可以爲每個存在的文件夾創建單個進程嗎?

除此之外,我會運行索引,但只有所有進程完成後。

我可以使用load.wait(),但只適用於一個進程。

感謝的建議和幫助提前

編輯新增:

以史蒂夫的意見,我介紹了一些線程,但它仍然會導致索引啓動子進程完成之前

def threads(self): 
    processors = multiprocessing.cpu_count() 
    n = 1 
    name = "sql%i" %n 
    for i in range(processors): 
     if os.path.exists(name): 
    thread = Thread(target=self.loadData, args=(name,)) 
    thread.start()    
    n += 1 
    name = "sql%i" %n 

def loadData(self, name): 
    for files in os.listdir(name): 
    load = subprocess.Popen("psql -d osdata -U postgres -f %s\%s" %(name, files)) 
    load.wait()                                             

但索引在過程完成之前開始。

任何想法如何防止

+0

你需要做的thread.wait()如果你想阻止,直到線程完成。 Python的期貨模塊可能是你想用來使「運行X線程」微不足道的。我已將這添加到我的答案中。 –

+0

與其開始單獨的'psql'會話,不如考慮使用'subprocess'模塊以雙向管道打開單個會話。用Python讀取每個sql文件並將其寫入psql的stdin。從stdout和stderr讀取結果。 –

回答

0

我會建議爲每個文件夾創建一個線程。然後使用subprocess.call來串行化每個線程中的調用。

如果你想限制併發執行的線程數量,你應該看看Python的期貨模塊。

http://docs.python.org/dev/library/concurrent.futures.html

from concurrent.futures import ThreadPoolExecutor 

with ThreadPoolExecutor(max_workers=2) as executor: 
    for n in range(processors): 
     name = "sql%i" % (n + 1) 
     if os.path.exists(name): 
      future = executor.submit(loadData, name) 
+0

嗨,史蒂夫。感謝您的答覆。請參閱我上面的編輯以及您是否對解決方案有任何想法。 – tjmgis

+0

修改我的答案 –

+1

嗨史蒂夫看起來像它的工作。我使用Python 2.7時必須安裝PIP和期貨。我沒有完全理解它,但從我可以告訴它限制進程的數量並等待它們全部完成,然後再轉到代碼的下一部分。非常感謝你。 – tjmgis