我在Python 3.3中编写了一个脚本,它对PostgreSQL数据库进行查询。我正在使用子流程和 Popen ,它可以工作,但我很新做这个,我想我不知道它是如何实际工作的。我的问题是:
做完Popen后我必须关闭任何东西吗?
我阅读了一些说是的论坛和教程,但是当我对查询结果执行kill或其他命令时,很明显,我会收到类似这样的消息:
'list'对象没有属性'kill'
我试过信号和killpg,任何想法?这是我的两个代码查询:
database_list = subprocess.Popen('echo "select datname from pg_database" '
'| psql -t -U %s -h %s template1' %
(bkp_vars['user'], bkp_vars['host']),
shell=True,
stdout=subprocess.PIPE).stdout.readlines()
update_result = subprocess.Popen('echo "UPDATE pg_database SET datallowconn = TRUE WHERE datname = \'template0\'" '
'| psql -t -U %s -h %s template1' %
(bkp_vars['user'],bkp_vars['host']), shell=True,
stdout=subprocess.PIPE).stdout.readlines()
提前谢谢!
答案 0 :(得分:4)
首先,对于psycopg2
(PostgreSQL的Python接口)而言,这比使用subprocess
和psql
要好得多。
此外,如果您正在进行备份,则应该使用pg_dump
和pg_restore
,而不是弄乱psql
。
import psycopg2
# Replace connection parameters with those for your DB; see the psycopg2 docs
conn = psycopg2.connect("dbname=postgres user=myusername password=whatever")
curs = conn.cursor()
curs.execute("select datname from pg_database;")
dbs = curs.fetchall()
print dbs
subprocess
如果你必须使用psql
,那么你需要意识到Popen
会返回subprocess.Popen
object。
这些表示子进程。您可以将它们用于wait for the child process to finish,以读取子进程输出等。
大多数情况下,您将使用诸如subprocess.check_call
和subprocess.check_output
之类的包装器接口,这样可以自动执行此操作并使其更容易换取灵活性降低。在您的情况下,我认为您需要subprocess.check_output
。
subproces
可用于将stdin
写入对象,方法是传递包含所需stdin的临时文件,或者直接写入Popen
构造函数返回的stdin文件句柄。您不应该像echo
stdin那样通过subprocess
模块打开进程。
如果您必须使用psql
执行此操作,则需要更多类似的内容:
import subprocess
username = "postgres"
dbname = "postgres"
p = subprocess.Popen(
args = ['psql', '-qAt', '-0', '-U', username, dbname],
stdin = subprocess.PIPE,
stdout = subprocess.PIPE
)
p.stdin.write("SELECT datname FROM pg_database;");
p.stdin.close()
dbs = p.stdout.read().split('\0')
print dbs
p.wait()
请注意使用空字节作为记录分隔符,因此可以正确解析其中包含换行符的数据库名称。