RuntimeWarning: сопрограмма никогда не ожидалась с помощью утилиты bcp - PullRequest
0 голосов
/ 04 марта 2020

Цель

Используя asyncio, асинхронно запустить утилиту bcp, чтобы извлечь несколько таблиц в .dat файлы. Команды, запускаемые независимо, дают ожидаемые результаты. Команды также успешно выполняются при последовательном выполнении через subprocess.run. Поверьте, ошибка связана с тем, как я использую или не использую await.

Ошибка

Traceback (most recent call last):
  File "bcp_out_all.py", line 38, in <module>
    asyncio.run(windows_loop([cmd_ for cmd_ in bcp_cmds]))
  File "C:\Users\hSin\AppData\Local\Continuum\anaconda3\envs\ELT\lib\asyncio\runners.py", line 43, in run
    return loop.run_until_complete(main)
  File "C:\Users\hSin\AppData\Local\Continuum\anaconda3\envs\ELT\lib\asyncio\base_events.py", line 583, in run_until_complete
    return future.result()
  File "bcp_out_all.py", line 14, in windows_loop
    loop.run_until_complete(parallel_bcp(cmd_))
  File "C:\Users\hSin\AppData\Local\Continuum\anaconda3\envs\ELT\lib\asyncio\base_events.py", line 570, in run_until_complete
    self.run_forever()
  File "C:\Users\hSin\AppData\Local\Continuum\anaconda3\envs\ELT\lib\asyncio\base_events.py", line 528, in run_forever
    'Cannot run the event loop while another loop is running')
RuntimeError: Cannot run the event loop while another loop is running
sys:1: RuntimeWarning: coroutine 'parallel_bcp' was never awaited

Скрипт

#bcp_out_all.py
import asyncio

#commands successfully run in PowerShell terminal
bcp_cmds = [['bcp db.schema.tbl_1 OUT tbl_1.dat -e tbl_1_error.dat -T -n -t"|" -S SRVRNAME'], ['bcp db.schema.tbl_2 OUT tbl_2.dat -e tbl_2_error.dat -T -n -t"|" -S SRVRNAME']]


async def parallel_bcp(cmd_):
    process = await asyncio.create_subprocess_exec(cmd_, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE)
    await process.wait()

async def windows_loop(cmd_):
    loop = asyncio.ProactorEventLoop()
    asyncio.set_event_loop(loop)
    loop.run_until_complete(parallel_bcp(cmd_))

asyncio.run(windows_loop([cmd_ for cmd_ in bcp_cmds]))

1 Ответ

0 голосов
/ 05 марта 2020

смог найти решение на основе этого вопроса; Как передать строку в subprocess.run, используя stdin в Python 3 , однако его применение касалось Python 3.7, а команда передавалась в виде списка строк, что моя команда список был изменен на. Наконец, subprocess использовалось вместо asyncio.

Обновленный сценарий:

from subprocess import Popen

procs_list = ['bcp db.schema.tbl_1 OUT tbl_1.dat -e tbl_1_error.dat -T -n -t"|" -S SRVRNAME', 'bcp db.schema.tbl_2 OUT tbl_2.dat -e tbl_2_error.dat -T -n -t"|" -S SRVRNAME']

for proc in procs_list:
   Popen(proc, text=True)

Окончательный сценарий:

Завершено без необходимости использования asyncio, и воспользовался Popen.

tbls_lst = ['tbl1', 'tbl2']

procs_lst = ['bcp db.schema.' + tbl + ' OUT ' + tbl + '.dat' + '-T -n -t"|" -S SRVRNAME -b 5000' for tbl in tbls_lst]

try:
    for proc in procs_lst:
        process = subprocess.Popen(
                proc,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                text=True)
        output, error = process.communicate()
        if output:
            print("Output returned: ", process.returncode)
        if error:
            print("Error returned: ", process.returncode)
            print("Error:", error.strip())
except OSError as e:
    print("OSError: ", e.errno)
    print("OSError: ", e.strerror)
    print("OSError: ", e.filename)
except:
    print("Error: ", sys.exc_info()[0])
...