2

我在尝试从 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 个问题位于 此处此处

蟒蛇程序:

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());
4

1 回答 1

3

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

一个通常更好的选择是让触发器发送一个NOTIFY并有一个带有 PostgreSQL 连接的进程LISTEN用于通知。当收到通知时,该进程可以启动您的程序。这是我推荐的方法;它更简洁,这意味着您的程序不必在 PostgreSQL 的用户 ID 下运行。见NOTIFYLISTEN

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

您可以PL/Pythonu使用os.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 代码一样,使用copyshell 命令在 C++ 中复制文件通常是错误的。Microsoft WindowsCopyFile为此提供了功能;其他平台上存在等价物或替代品,您也可以使用可移植但效率较低的流复制。

于 2013-03-10T07:25:30.293 回答