Python没有调用外部程序第3部分

时间:2013-03-09 22:54:49

标签: c++ python postgresql

我一直在尝试从postgres 9.2数据库中的触发器生成的python程序运行外部程序时遇到问题。触发器有效。它写入文件。我曾尝试过只运行外部程序,但权限不允许它运行。我能够创建一个文件夹(使用os.system(“mkdir”))。该文件夹的所有者是NETWORK SERVICE。

我需要运行一个名为sdktest的程序。当我尝试运行它时没有响应发生,所以我认为这意味着python程序没有足够的权限(使用NETWORK SERVICE的所有者)来运行它。

我一直把我需要的程序复制文件放到那个目录中,这样他们才能拥有正确的权限,并且在某种程度上有效,但是我需要运行的程序是最后一个而且它没有运行,因为它没有足够的权限。

我的python程序运行一个名为PG_QB_Connector的C ++程序,它调用sdktest。

我有什么方法可以将流程的所有者更改为“正常”所有者?有一个更好的方法吗?基本上我只需要让这个C ++程序有足够的权限来正确运行。

顺便说一句,当我手动运行C ++程序时,运行sdktest程序的行正确运行,但是,当我从postgres / python运行它时它没有做任何事情......

我有Windows 7,python 3.2。我询问的其他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的C ++程序位于

之下
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());

1 个答案:

答案 0 :(得分:3)

听起来你想从PostgreSQL触发器或函数中调用命令行程序。

通常更好的选择是让触发器发送NOTIFY并使用PostgreSQL连接进程LISTEN进行通知。当收到通知时,该过程可以启动您的程序。这是我建议的方法;它更清洁,这意味着你的程序不必在PostgreSQL的用户ID下运行。请参阅NOTIFYLISTEN

如果你真的需要从Pg内部运行命令:

您可以os.systemsubprocess.check_call使用PL/Pythonu; 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功能;在其他平台上存在等价物或替代品,您也可以使用便携式但效率较低的流复制。