2015-06-25 6 views
0

Я бегу следующий кусок кода Python (запускает команду в оболочке и хватает его выход или сообщение об ошибке)Python подпроцесс свисает с командой Psql

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 на 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 одной команды другой, но ее невозможно изменить на данный момент.

Запуск та же команда из Баш непосредственно работает, как ожидалось, также работает без shell=True работы

+1

Полная остановка. Вы изобретаете https://docs.python.org/2/library/subprocess.html#subprocess.check_output, игнорируя способность Python напрямую общаться с PostgreSQL (с https://pypi.python.org/pypi/psycopg2 для пример), и вы делаете это таким образом, который уязвим для SQL-инъекции. Не пойди так, пожалуйста. – ElmoVanKielmo

+0

@ElmoVanKielmo это устаревший код, и, к сожалению, мне нужно его исправить. Я попробую ваше предложение на 'check_output'. Я не могу использовать 'psycopg' напрямую, потому что обычно запросы сложнее, и иногда им приходится обращаться к внешним двоичным файлам. – iggy

+0

@ElmoVanKielmo есть ли у вас какие-либо идеи, почему написанный в настоящее время код не работает? – iggy

ответ

0

Проблема заключалась в том, что я не фильтровать символы новой строки в лексемы, переданных check_output, то снаряд вешают ждет более вход. Поэтому удостоверьтесь, что вы избегаете токенов, когда вы передаете их в оболочку.

Смежные вопросы