2013-03-09 60 views
2

我一直有問題,試圖從一個從postgres 9.2數據庫中的觸發器生成的python程序運行一個外部程序。觸發器起作用。它寫入文件。我曾嘗試過只運行外部程序,但權限不允許它運行。我能夠創建一個文件夾(使用os.system(「mkdir」))。該文件夾的所有者是NETWORK SERVICE。Python不調用外部程序部分3

我需要運行一個名爲sdktest的程序。當我嘗試運行它時,沒有響應發生,所以我認爲這意味着python程序沒有足夠的權限(使用NETWORK SERVICE的所有者)來運行它。

我一直有我的程序複製文件,它需要進入該目錄,所以他們將有正確的權限,並已在一定程度上工作,但我需要運行的程序是最後一個,它不運行,因爲它沒有足夠的權限。

我的python程序運行一個名爲PG_QB_Connector的C++程序,它調用sdktest。

有沒有什麼辦法可以將進程的擁有者更改爲「普通」擁有者?有一個更好的方法嗎?基本上我只需要讓這個C++程序有足夠的perms來正確運行。

BTW,當我用手運行C++程序,運行該程序sdktest線運行正常,然而,當我從Postgres的/蟒蛇它沒有做任何事情,運行它...

我有Windows 7,Python 3.2。我問這個的其他兩個問題分別位於herehere

Python程序:

CREATE or replace FUNCTION scalesmyone (thename text) 
RETURNS int 
AS $$ 
a=5 
f = open('C:\\JUNK\\frompython.txt','w') 
f.write(thename) 
f.close() 
import os 
os.system('"mkdir C:\\TEMPWITHOWNER"') 
os.system('"mkdir C:\\TEMPWITHOWNER\\addcustomer"') 
os.system('"copy C:\\JUNK\\junk.txt C:\\TEMPWITHOWNER\\addcustomer"') 
os.system('"copy C:\\BATfiles\\junk6.txt C:\\TEMPWITHOWNER\\addcustomer"') 
os.system('"copy C:\\BATfiles\\run_addcust.bat C:\\TEMPWITHOWNER\\addcustomer"') 
os.system('"copy C:\\Workfiles\\PG_QB_Connector.exe C:\\TEMPWITHOWNER\\addcustomer"') 
os.system('"copy C:\\Workfiles\\sdktest.exe C:\\TEMPWITHOWNER\\addcustomer"') 
import subprocess 
return_code = subprocess.call(["C:\\TEMPWITHOWNER\\addcustomer\\PG_QB_Connector.exe", '"hello"']) 
$$ LANGUAGE plpython3u; 

是從Python程序調用,調用sdktest.exe低於

command = "copy C:\\Workfiles\\AddCustomerFROMWEB.xml C:\\TEMPWITHOWNER\\addcustomer\\AddCustomerFROMWEB.xml"; 
system(command.c_str()); 


//everything except for the qb file is in my local folder 
command = "C:\\TEMPWITHOWNER\\addcustomer\\sdktest.exe \"C:\\Users\\Public\\Documents\\Intuit\\QuickBooks\\Company Files\\Shain Software.qbw\" C:\\TEMPWITHOWNER\\addcustomer\\AddCustomerFROMWEB.xml C:\\TEMPWITHOWNER\\addcustomer\\outputfromsdktestofaddcust.xml"; 
system(command.c_str()); 
的C++程序
+1

我是否正確理解PostgreSQL觸發器正在生成一個Python程序並將其寫入一個文件,然後您想從C++程序中調用該文件?這種設計看起來非常奇怪,我懷疑,而不是做目前的設計工作,可能需要改變方法。你知道PL/Python嗎?您是否考慮過在您的C++程序中嵌入Python解釋器,通過libpq連接從Pg獲取程序文本並在嵌入式Python解釋器中執行它? – 2013-03-10 02:03:40

+0

@CraigRinger,不,那不是我想要做的。在最基本的形式中,我希望來自postgres的觸發器能夠運行我創建的名爲PG_QB_Connector的C++程序。該程序將執行一些處理並調用sdktest。我甚至不關心python作爲postgres的一部分。我只需要一些方法讓postgres觸發器運行程序。至於你的建議,我不認爲你的libq連接會有幫助,是嗎?我是否正確地認爲我需要一個來自PG的連接,而不是進入? – Jim 2013-03-10 03:48:28

+0

是的,你正在嘗試做一些與我以前不同的事情。現在添加答案。 – 2013-03-10 07:20:20

回答

3

這聽起來像你想從PostgreSQL觸發器或函數中調用命令行程序。

一個比較好的選擇是讓觸發器發送一個NOTIFY並且有一個PostgreSQL連接的進程LISTEN用於通知。當通知進入時,該過程可以啓動您的程序。這是我建議的方法;它更加清潔,這意味着您的程序不必在PostgreSQL的用戶標識下運行。見NOTIFYLISTEN

如果你真的需要從內部PG運行命令:

您可以使用PL/Pythonuos.systemsubprocess.check_call; PL/Perlusystem();如果需要的話,所有這些都可以從Pg內部運行命令。你不能直接從PostgreSQL調用程序,你需要使用'不可信'(意思是完全特權的,而不是沙盒)過程語言來調用外部可執行文件。 PL/TCL也可能做到這一點。

更新:如上圖所示

Python代碼有幾個問題:

  • 使用Python中os.system複製文件是錯誤的。使用shutil庫:http://docs.python.org/3/library/shutil.html複製文件,以及簡單的os.mkdir命令來創建目錄。
  • 雙層引用看起來不對;你是不是隻想引用每個論點而不是整個命令?無論如何,你應該使用subprocess.call而不是os.system
  • 您的最終subprocess.call調用顯示正常,但未能檢查錯誤代碼,因此您永遠不會知道它是否出錯;您應該改用subprocess.check_call

C++代碼似乎也無法檢查system()調用中的錯誤,因此您永遠不會知道它運行的命令是否失敗。

與Python代碼類似,使用copy shell命令複製C++文件通常是錯誤的。 Microsoft Windows爲此提供了CopyFile函數;等價物或替代品存在於其他平臺上,您也可以使用便攜式但效率較低的流式複製。

+0

我有使用plpython3u的vbeen。我選擇它是因爲它「不可信」。 os.system是我一直在運行的,這就是我一直遇到的問題....我正在查看NOTIFY和LISTEN,並將回答您的問題。謝謝!! – Jim 2013-03-10 14:07:28

+0

@Jim在您的Python代碼中添加註釋。你沒有收到錯誤,因爲你沒有要求在子進程出錯時拋出異常,而且你也沒有檢查返回碼。 – 2013-03-10 14:12:28

+0

複製文件和文件夾不是該項目的目標。那只是爲了測試目的。目標是讓exe運行。其他一切都只是爲了測試目的,看看我是否可以運行EXE。我不明白NOTIFY/LISTEN會如何幫助...我認爲他們只是在內部對象上工作。你能否按照你認爲的方式給我一個樣本?謝謝, – Jim 2013-03-10 18:52:42