subprocess.run
является рекомендуемым подходом к Python 3.5 , если вашему коду не требуется поддерживать совместимость с более ранними версиями Python. Это более последовательно и предлагает аналогичную простоту использования в качестве посланника. (Трубопровод не так прост. См. этот вопрос, как .)
Вот несколько примеров из документов .
Запустите процесс:
>>> subprocess.run(["ls", "-l"]) # doesn't capture output
CompletedProcess(args=['ls', '-l'], returncode=0)
Поднять при неудачном прогоне:
>>> subprocess.run("exit 1", shell=True, check=True)
Traceback (most recent call last):
...
subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1
Выход захвата:
>>> subprocess.run(["ls", "-l", "/dev/null"], stdout=subprocess.PIPE)
CompletedProcess(args=['ls', '-l', '/dev/null'], returncode=0,
stdout=b'crw-rw-rw- 1 root root 1, 3 Jan 23 16:23 /dev/null\n')
Я рекомендую попробовать Envoy . Это оболочка для подпроцесса, которая, в свою очередь, стремится заменить более старые модули и функции. Посланник является подпроцессом для людей.
Пример использования из readme :
>>> r = envoy.run('git config', data='data to pipe in', timeout=2)
>>> r.status_code
129
>>> r.std_out
'usage: git config [options]'
>>> r.std_err
''
Материал трубы тоже:
>>> r = envoy.run('uptime | pbcopy')
>>> r.command
'pbcopy'
>>> r.status_code
0
>>> r.history
[]
В документации из execute
упоминается, что метод возвращает итератор с результатами для каждого запроса при multi=True
. Кажется, что запросы ничего не делают, пока итератор не будет обработан, независимо от commit()
. Однако операторы CREATE
не дают никаких результатов, и попытка перебрать возвращаемое значение execute
приводит к исключению: generator raised StopIteration
. Это связано с ошибкой в модуле коннектора и исправлено в версии 8.0.13 с поддержкой python 3.7.
Решение теперь состоит в том, чтобы всегда перебирать возвращаемое значение execute
, даже если никаких ожидаемых данных не ожидается, и обновлять соединительный модуль. Если обновление невозможно, можно отследить неудачную итерацию и продолжить.
Фиксированный код (включая часть для более ранних версий соединительного модуля) теперь выглядит примерно так:
try:
results = cursor.execute(script, multi=True)
try:
for result in results:
pass
except Exception as e:
pass
warnings = cursor.fetchwarnings()
if warnings:
for warning in warnings:
# handle warning
connection.commit()
cursor.close()
connection.close()
except mysql.connector.Error as err:
# handle error
Попробуйте использовать пароль = "somepassword" вместо passwd = "somepassword". И удалить мульти = True. Это создаст предупреждение, но все равно выполнит оба ваших утверждения.