subprocess.popen和psql

时间:2011-02-16 17:17:02

标签: python django postgresql subprocess psql

我有需要调用psql的Django应用程序。我在芹菜线中做到这一点,看起来像这样:

@task()
def insert_sqldump_threaded(username, database, file):
  host = database.server.db_address

  work = subprocess.Popen([settings.PSQL, 
                          "-f%s" % file, 
                          "-d%s" % database.db_name,
                          "-h%s" % host,
                          "-U%s" % settings.DB_ADMIN_USER
                          ], env = {'PGPASSFILE': settings.DB_PASSFILE}
                          )
  work.wait()
  return work.returncode

在我的开发服务器上,PGPASSFILE如下所示:

localhost:5432:*:postgres:postgres

应该没问题。

问题是,当调用此函数时我得到的是来自psql的错误:

psql: could not translate host name "localhost" to address: Unknown server error

现在它变得非常奇怪,但是当我不提交“env”变量时,psql似乎认出了主机。至少它会要求输入密码。

关于如何解决这个问题的任何想法?

2 个答案:

答案 0 :(得分:3)

我认为postgresql需要在传递env时清除的其他环境变量。您可以直接更改os.environ或预先复制它,如下面的代码所示:

import os
@task()
def insert_sqldump_threaded(username, database, file):
  d = dict(os.environ)
  d['PGPASSFILE'] = settings.DB_PASSFILE
  host = database.server.db_address

  work = subprocess.Popen([settings.PSQL, 
                          "-f%s" % file, 
                          "-d%s" % database.db_name,
                          "-h%s" % host,
                          "-U%s" % settings.DB_ADMIN_USER
                          ], env = d
                          )
  work.wait()
  return work.returncode

答案 1 :(得分:0)

如果您不提交env,它会从您正在运行的shell中获取环境变量 - 请参阅os.environ。它必须依赖于其中一个查找localhost。你需要在字典中包含它。或者只是复制os.environ中的所有内容。