subprocess.popen 和 psql
我有一个Django应用程序,需要调用psql(PostgreSQL的命令行工具)。我是在一个celery线程中这样做的,代码看起来是这样的:
@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
当你不提交环境变量时,它会从你正在使用的命令行环境中获取这些变量——可以参考一下os.environ。它可能是依赖这些变量来查找本地服务器的。你需要把这些变量放进字典里。或者直接把os.environ里的所有内容都复制过来。
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