2014-04-25 46 views
0

我正在運行一個調用子進程的python腳本。它超時,然後立即看到子過程(在這種情況下是BCP調用)完成。事實上,我可以看到它在數據庫中完整。另外,我可以直接在命令行上運行BCP命令,它工作得很好。從python調用BCP會引發超時異常,然後立即完成

這裏是我的python腳本吐出到命令提示符:

C:\FaceIAPS\StudyDataFiles> py .\RUN_DATA.py 
Synchronizing 80 subjects 
Subject 11 

Starting copy... 
Traceback (most recent call last): 
    File ".\RUN_DATA.py", line 261, in <module> 
    bulk_import(upload_file, 'Facet_Data') 
    File ".\RUN_DATA.py", line 171, in bulk_import 
    subprocess.check_call("bcp BehaviorResearch.." + table_to_upload_to + " in " +  filename_to_be_uploaded + " -T -c -S 
PBB-C202B-2\BEHAVIORRESEARCH -e bulk_copy_errors.log", shell=True, timeout=5) 
    File "C:\Python34\lib\subprocess.py", line 554, in check_call 
    retcode = call(*popenargs, **kwargs) 
    File "C:\Python34\lib\subprocess.py", line 537, in call 
    return p.wait(timeout=timeout) 
    File "C:\Python34\lib\subprocess.py", line 1157, in wait 
    raise TimeoutExpired(self.args, timeout) 
subprocess.TimeoutExpired: Command 'bcp BehaviorResearch..Facet_Data in _temp_ -T -c -S  PBB-C202B-2\BEHAVIORRESEARCH -e 
bulk_copy_errors.log' timed out after 5 seconds 
1000 rows sent to SQL Server. Total sent: 1000 
1000 rows sent to SQL Server. Total sent: 2000 
PS C:\FaceIAPS\StudyDataFiles> 1000 rows sent to SQL Server. Total sent: 3000 
1000 rows sent to SQL Server. Total sent: 4000 
1000 rows sent to SQL Server. Total sent: 5000 
1000 rows sent to SQL Server. Total sent: 6000 
1000 rows sent to SQL Server. Total sent: 7000 
1000 rows sent to SQL Server. Total sent: 8000 
1000 rows sent to SQL Server. Total sent: 9000 
1000 rows sent to SQL Server. Total sent: 10000 
1000 rows sent to SQL Server. Total sent: 11000 
1000 rows sent to SQL Server. Total sent: 12000 
1000 rows sent to SQL Server. Total sent: 13000 
1000 rows sent to SQL Server. Total sent: 14000 
1000 rows sent to SQL Server. Total sent: 15000 
1000 rows sent to SQL Server. Total sent: 16000 

16102 rows copied. 
Network packet size (bytes): 4096 
Clock Time (ms.) Total  : 5164 Average : (3118.13 rows per sec.) 

正如你所看到的,在命令提示符下已經分裂與BCP調用的輸出。
怎麼回事,我該如何解決?

編輯:我如何固定它

更改子呼籲:「在」

arguments = ["bcp", "BehaviorResearch.." + table_to_upload_to, "in", filename_to_be_uploaded, "-T", "-c", "-S PBB-C202B-2\BEHAVIORRESEARCH", "-e bulk_copy_errors.log"] 
subprocess.call(arguments, timeout=30) 

作爲一個供參考的門外漢,是它自己的說法。

+0

你問的是什麼問題? – AHuman

回答

4

subprocess.check_call() say用於該文檔:

超時參數被傳遞給Popen.wait()。如果超時 到期,子進程將被終止,然後再次等待。 在子進程 終止後,將會重新啓動TimeoutExpired異常。

subprocess source code證實了這一點:

def call(*popenargs, timeout=None, **kwargs): 
    with Popen(*popenargs, **kwargs) as p: 
     try: 
      return p.wait(timeout=timeout) 
     except: 
      p.kill() # kill on any exception including TimeoutExpired 
      p.wait() 
      raise 

也就是說,你看到的是預期的行爲:如果發生超時,然後運行該BCP過程中,應及時是終止外殼(%COMSPEC%cmd.exe)反過來可能會終止bcp進程本身。

你看被刷新在控制檯緩衝輸出後的子進程已經退出(我不知道),你看到活着的孫子BCP過程的輸出,而其母公司cmd.exe已經完成的(新的提示是示出)。

刪除shell=True以避免創建不必要的中間進程cmd.exe進程,以便直接在bcp進程上調用.kill()而不是shell進程。

+0

這是正確的。無論出於何種原因,shell都有問題,但bcp工作得很好。最終,爲了繞過shell,我不得不刪除shell = True。我還必須重新編寫調用以將每個參數傳遞到列表中。 –

相關問題