#python #python-decorators #bonobo-etl
#python #python-декораторы #bonobo-etl
Вопрос:
В документации bonobo у них есть следующий пример настройки зависимости от службы:
from bonobo.config import use
@use('orders_database')
def select_all(database):
yield from database.query('SELECT * FROM foo;')
Я попытался сделать что-то подобное и получил сообщение об ошибке. Вот очень упрощенная версия моего скрипта:
import bonobo
from bonobo.config import use
from ftplib import FTP
def get_services(**options):
ftp_1 = FTP('ftp.gnu.org')
ftp_1.login()
ftp_1.cwd('gnu/emacs')
return{
'ftp1': ftp_1,
}
@use('ftp1')
def listen_for_file(ftp):
test = ftp.nlst('README.olderversions')
if test:
print( 'Found file')
return True
else:
print('File not found in ftp')
return False
def get_graph(**options):
graph = bonobo.Graph()
graph.add_chain(listen_for_file)
return graph
if __name__ == '__main__':
parser = bonobo.get_argument_parser()
with bonobo.parse_args(parser) as options:
bonobo.run(get_graph(**options), services=get_services(**options))
Если я попытаюсь запустить это, я получу следующую ошибку:
КРИТИЧЕСКИЙ:bonobo.execution.contexts.base:<NodeExecutionContext( listen_for_file) in=1 ошибка =1> Трассировка (последний последний вызов): Файл «C:UsersmfrantsAppDataLocalProgramsPythonPython37libsite-packagesbonoboconfigprocessors.py» , строка 102, в файле call bound = self._bind(_input) «C:UsersmfrantsAppDataLocalProgramsPythonPython37libsite-packagesbonoboconfigprocessors.py» , строка 89, в _bind возвращаетпривязать (* self.args, *_input, ** self.kwargs) файл «C:UsersmfrantsAppDataLocalProgramsPythonPython37libinspect.py «, строка 3015, в привязке возвращает args[0]._bind(args[1:], kwargs) Файл «C:UsersmfrantsAppDataLocalProgramsPythonPython37libinspect.py «, строка 2930, в _bind поднять TypeError(msg) из None TypeError: отсутствует обязательный аргумент: ‘ftp’
Приведенное выше исключение было прямой причиной следующего исключения:
Обратная трассировка (последний последний вызов): Файл «C:UsersmfrantsAppDataLocalProgramsPythonPython37libsite-packagesbonoboexecutioncontextsnode.py» , строка 102, в файле loop self.step() «C:UsersmfrantsAppDataLocalProgramsPythonPython37libsite-packagesbonoboexecutioncontextsnode.py» , строка 129, в результатах шага = self._stack(input_bag) Файл «C:UsersmfrantsAppDataLocalProgramsPythonPython37libsite-packagesbonoboconfigprocessors.py» , строка 114, в вызове) из exc bonobo.ошибки.Ошибка неисправимого типа: ввод <функция listen_for_file в 0x000002A591047F78> не привязывается к подписи узла. Аргументы: () Ввод: () Kwargs: {‘ftp1’:FTP-объект в 0x000002A5910CF708>} Подпись: (ftp)
Единственный способ запустить его — это изменить ftp на ftp1 в функции listen_for_file. Что я здесь делаю не так?
Комментарии:
1. > Единственный способ запустить его — это изменить ftp на ftp1 в функции listen_for_file. Да, это звучит разумно для меня. Потому что имя ссылки должно совпадать с тем, о чем я думаю.
2. @FonyLew, значит, он работает так, как задумано? Потому что пример, который я привел со страницы документации, имеет разные имена (‘orders_database’ в use decorator и ‘database’ в определении функции).
Ответ №1:
bonobo строго относится к именованию переменных, хотя этого не должно быть.
Для использования config.use
лучше использовать точное имя службы в сигнатуре функции и сохранить его в качестве последнего параметра.
Чтобы изменить фактического поставщика услуг, который вы хотите использовать, вам необходимо изменить карту в вашей get_services
функции.
import bonobo
from bonobo.config import use
from ftplib import FTP
def get_services(**options):
ftp_1 = FTP(options.get('ftp_server') or 'ftp.gnu.org')
ftp_1.login()
ftp_1.cwd('gnu/emacs')
return{
'ftp': ftp_1,
}
@use('ftp')
def listen_for_file(ftp):
test = ftp.nlst('README.olderversions')
if test:
print( 'Found file')
return True
else:
print('File not found in ftp')
return False
def get_graph(**options):
graph = bonobo.Graph()
graph.add_chain(listen_for_file)
return graph
if __name__ == '__main__':
parser = bonobo.get_argument_parser()
parser.add('--ftp_server')
with bonobo.parse_args(parser) as options:
bonobo.run(get_graph(**options), services=get_services(**options))
Комментарии:
1. Спасибо, @PyGuy, это делает то, что я хочу.