Я бегу следующий кусок кода 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
работы
Полная остановка. Вы изобретаете https://docs.python.org/2/library/subprocess.html#subprocess.check_output, игнорируя способность Python напрямую общаться с PostgreSQL (с https://pypi.python.org/pypi/psycopg2 для пример), и вы делаете это таким образом, который уязвим для SQL-инъекции. Не пойди так, пожалуйста. – ElmoVanKielmo
@ElmoVanKielmo это устаревший код, и, к сожалению, мне нужно его исправить. Я попробую ваше предложение на 'check_output'. Я не могу использовать 'psycopg' напрямую, потому что обычно запросы сложнее, и иногда им приходится обращаться к внешним двоичным файлам. – iggy
@ElmoVanKielmo есть ли у вас какие-либо идеи, почему написанный в настоящее время код не работает? – iggy