Python子进程使用psql命令挂起

时间:2015-06-25 11:00:47

标签: python postgresql psql

我正在运行以下的python代码(在shell中运行命令并获取其输出或报告错误)

import sys
import subprocess
def check_output(args, communicate=None, quiet=False, **kwargs):
    for stream in ["stdout", "stderr"]:
        kwargs.setdefault(stream, subprocess.PIPE)

    proc = subprocess.Popen(args, **kwargs)
    try:
        out, err = proc.communicate()
    finally:
        for f in (proc.stdout, proc.stderr):
            if f is not None:
                f.close()
        proc.wait()

    if kwargs["stderr"] != subprocess.PIPE:
        err = ""

    if proc.returncode != 0:
        raise Exception(args, proc.returncode, err)
    else:
        if not quiet:
            sys.stderr.write(err)
            sys.stderr.flush()
    return out

使用以下参数:

env = dict(
        PGHOST='{pg_host}',
        PGPORT='{pg_port}',
        PGDATABASE='{pg_dbname}',
        PGUSER='{pg_user}',
        PGPASSWORD='{pg_password}',
      )

cmd = ['psql', '-c', "INSERT INTO {ft_geom} SELECT * FROM {ft_geom_in};"].format(**tables)
check_output(cmd, shell=True, env=env)

此处env只包含PG[HOST|USER|DATABASE|PORT|..]个环境变量,而tables只包含这两个表的名称。当我运行此代码时,它会在proc = subprocess.Popen调用时无限期挂起。我在2.6.5

上使用python Ubuntu 10.04.3 LTS

我检查没有表被锁定以下内容:

SELECT a.datname,
         c.relname,
         l.transactionid,
         l.mode,
         l.granted,
         a.usename,
         a.current_query, 
         a.query_start,
         age(now(), a.query_start) AS "age", 
         a.procpid 
    FROM  pg_stat_activity a
     JOIN pg_locks         l ON l.pid = a.procpid
     JOIN pg_class         c ON c.oid = l.relation
    ORDER BY a.query_start;

它表明所有的锁都被授予了。不知道还能在哪里看。我需要shell=True,因为命令有时更复杂,需要bash管道。我知道理想情况下我应该将stdout.PIPE的一个命令传递给另一个命令,但目前无法改变这一点。

直接从bash运行相同的命令可以按预期工作,也可以在没有shell=True的情况下运行

1 个答案:

答案 0 :(得分:0)

问题是我没有过滤传递给check_output的令牌中的换行符,然后shell会挂起等待更多输入。所以当你把它们传递给shell时,请确保你逃脱了它们。