【问题标题】:Python not calling an external program part 3Python 不调用外部程序第 3 部分
【发布时间】:2013-03-10 22:17:06
【问题描述】:

我在尝试从 python 程序运行外部程序时遇到问题,该程序是从 postgres 9.2 数据库中的触发器生成的。触发器起作用。它写入文件。我曾尝试只运行外部程序,但权限不允许它运行。我能够创建一个文件夹(使用 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。我问的另外两个问题位于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());

【问题讨论】:

  • 我是否正确理解 PostgreSQL 触发器正在生成 Python 程序并将其写入您想从 C++ 程序调用的文件中?这种设计充其量看起来非常奇怪。我怀疑与其使当前的​​设计工作,不如改变方法。你知道 PL/Python 吗?您是否考虑过在您的 C++ 程序中嵌入 Python 解释器,通过 libpq 连接从 Pg 获取程序文本并在嵌入式 Python 解释器中执行它?
  • @CraigRinger,不,这不是我想做的。在最基本的形式中,我希望来自 postgres 的触发器运行我创建的名为 PG_QB_Connector 的 C++ 程序。该程序将进行一些处理并调用 sdktest。我什至不关心 python 作为 postgres 的一部分。我只需要一些方法让 postgres 触发器运行程序。至于您的建议,我认为您的 libq 连接不会对此有所帮助,对吗?我是否认为我需要一个来自 PG 而不是进入的连接?
  • 是的,你正在尝试做一些与我想象的不同的事情。现在添加答案。
  • 您还需要检查错误并清理调用命令和执行复制文件和创建目录等任务的方式,以便使用语言工具而不是尝试调用 shell 命令。 +1 链接到您之前的问题。

标签: c++ python postgresql


【解决方案1】:

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

通常更好的替代方法是让触发器发送NOTIFY 并让一个进程与 PostgreSQL 连接 LISTENing 进行通知。当收到通知时,该进程可以启动您的程序。这是我推荐的方法;它更简洁,这意味着您的程序不必在 PostgreSQL 的用户 ID 下运行。请参阅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 函数;其他平台上存在等价物或替代品,您也可以使用可移植但效率较低的流复制。

【讨论】:

  • 我一直在使用 plpython3u。我选择它是因为它“不受信任”。 os.system 是我一直在运行的,这就是我一直遇到的问题......我正在查看 NOTIFY 和 LISTEN,并会向您提出问题。谢谢!!
  • @Jim 为您的 Python 代码添加了注释。您没有收到错误,因为您没有要求在子进程收到错误时引发异常,并且您没有检查返回码。
  • 复制文件和文件夹不是该项目的目标。那只是为了测试目的。目标是让 exe 运行。其他一切都只是为了测试目的,看看我是否可以让 EXE 运行。我看不到 NOTIFY/LISTEN 将如何帮助......我认为它们只适用于内部对象。你能给我一个样本,它按照你认为的方式工作吗?谢谢,
  • 一个特别展示如何设置它以运行 C++ 程序的示例。谢谢。
  • @Jim 不,我已经花了尽可能多的时间,我真的无法实现您的设计演示。监听和通知会有所帮助,因为您可以使用任何 PostgreSQL 客户端来调用您想要在任何用户帐户下的程序;您不必担心在NETWORKSERVICE 或(旧版本)postgres 用户帐户下运行东西。使用更少的令人困惑的权限问题更容易调试和跟踪。无论如何,我关于未能在我编辑的答案中检查subprocess.call 中的错误的观点是成立的。您应该使用check_callcheck_output
猜你喜欢
  • 1970-01-01
  • 2012-12-26
  • 1970-01-01
  • 1970-01-01
  • 2012-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多