Как использовать subprocess.run () для запуска запроса Hive? - PullRequest
0 голосов
/ 10 ноября 2018

Итак, я пытаюсь выполнить запрос улья с помощью модуля subprocess и сохранить вывод в файл data.txt, а также в журналы (в log.txt), но у меня, похоже, немного неприятностей. Я посмотрел на эту суть , а также на этот ТАК вопрос , но ни один из них, похоже, не дает мне того, что мне нужно.

Вот что я бегу:

import subprocess
query = "select user, sum(revenue) as revenue from my_table where user = 'dave' group by user;"
outfile = "data.txt"
logfile = "log.txt"

log_buff = open("log.txt", "a")
data_buff = open("data.txt", "w")

# note - "hive -e [query]" would normally just print all the results 
# to the console after finishing
proc = subprocess.run(["hive" , "-e" '"{}"'.format(query)],
                    stdin=subprocess.PIPE,
                    stdout=data_buff,
                    stderr=log_buff,
                    shell=True)

log_buff.close()
data_buff.close()

Я также изучил этот SO вопрос, касающийся subprocess.run () vs subprocess.Popen , и я считаю, что хочу .run(), потому что я хотел бы, чтобы процесс блокировался до завершения.

Окончательным выводом должен быть файл data.txt с результатами запроса, разделенными табуляцией, и log.txt со всеми журналами, созданными заданием куста. Любая помощь будет замечательной.

Обновление:

С помощью описанного выше способа я получаю следующий вывод:

log.txt

[ralston@tpsci-gw01-vm tmp]$ cat log.txt
Java HotSpot(TM) 64-Bit Server VM warning: Using the ParNew young collector with the Serial old collector is deprecated and will likely be removed in a future release
Java HotSpot(TM) 64-Bit Server VM warning: Using the ParNew young collector with the Serial old collector is deprecated and will likely be removed in a future release
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/home/y/share/hadoop-2.8.3.0.1802131730/share/hadoop/common/lib/slf4j-log4j12-1.7.10.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/home/y/libexec/tez/lib/slf4j-log4j12-1.7.10.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]

Logging initialized using configuration in file:/home/y/libexec/hive/conf/hive-log4j.properties

data.txt

[ralston@tpsci-gw01-vm tmp]$ cat data.txt
hive> [ralston@tpsci-gw01-vm tmp]$

И я могу убедиться, что процесс java / hive действительно запустился:

[ralston@tpsci-gw01-vm tmp]$ ps -u ralston
  PID TTY          TIME CMD
14096 pts/0    00:00:00 hive
14141 pts/0    00:00:07 java
14259 pts/0    00:00:00 ps
16275 ?        00:00:00 sshd
16276 pts/0    00:00:00 bash

Но похоже, что он не заканчивает и не записывает все, что я хотел.

1 Ответ

0 голосов
/ 10 ноября 2018

Так что мне удалось заставить это работать со следующей настройкой:

import subprocess
query = "select user, sum(revenue) as revenue from my_table where user = 'dave' group by user;"
outfile = "data.txt"
logfile = "log.txt"

log_buff = open("log.txt", "a")
data_buff = open("data.txt", "w")
# Remove shell=True from proc, and add "> outfile.txt" to the command
proc = subprocess.Popen(["hive" , "-e", '"{}"'.format(query), ">", "{}".format(outfile)],
                    stdin=subprocess.PIPE,
                    stdout=data_buff,
                    stderr=log_buff)
# keep track of job runtime and set limit
start, elapsed, finished, limit  = time.time(), 0, False, 60
while not finished:
    try:
        outs, errs = proc.communicate(timeout=10)
        print("job finished")
        finished = True
    except subprocess.TimeoutExpired:
        elapsed = abs(time.time() - start) / 60. 
        if elapsed >= 60:
            print("Job took over 60 mins")
            break 
        print("Comm timed out. Continuing")
        continue

print("done")

log_buff.close()
data_buff.close()

Который выдает результат по мере необходимости. Я знал о process.communicate(), но раньше это не сработало. Я полагаю, что проблема была связана с тем, что файл запроса с > ${outfile} не добавлялся в запрос улья.

Не стесняйтесь добавлять любые детали. Я никогда не видел, чтобы кому-то приходилось перебирать proc.communicate(), поэтому я скептически отношусь к тому, что могу делать что-то не так.

...