Ответ 1
Вот несколько решений:
1. Переопределите BashOperator
чтобы добавить некоторые значения в контекст
class NextExecutionDateAwareBashOperator(BashOperator):
def render_template(self, attr, content, context):
dag = context['dag']
execution_date = context['execution_date']
context['next_execution_date'] = dag.following_schedule(execution_date)
return super().render_templates(attr, content, context)
# or in python 2:
# return super(NextExecutionDateAwareBashOperator, self).render_templates(attr, content, context)
Хорошая часть этого подхода: вы можете записать некоторый повторяющийся код в свой пользовательский оператор.
Плохая часть: вы должны написать пользовательский оператор для добавления значений в контекст, прежде чем будут отображены шаблонные поля.
2. Сделайте ваши вычисления в пользовательском макросе
Макросы не обязательно являются значениями. Они могут быть функциями.
В твоем даге
def compute_next_execution_date(dag, execution_date):
return dag.following_schedule(execution_date)
dag = DAG(
'simple',
schedule_interval='0 21 * * *',
user_defined_macros={
'next_execution_date': compute_next_execution_date,
},
)
task = BashOperator(
task_id='bash_op',
bash_command='echo "{{ next_execution_date(dag, execution_date) }}"',
dag=dag,
)
Хорошая часть: вы можете определить многократно используемые функции для обработки значений, доступных во время выполнения (значения XCom, свойства экземпляра задания, свойства экземпляра задачи и т.д.), И сделать свой результат функции доступным для визуализации шаблона.
Плохая часть (но не такая раздражающая): вам нужно импортировать такую функцию, как пользовательский макрос, в каждый тег, где это необходимо.
3. Назовите ваше выражение прямо в вашем шаблоне
Это самое простое (как уже упоминалось в ответе Ардана) и, вероятно, хорошее в вашем случае.
BashOperator(
task_id='bash_op',
bash_command='echo "{{ dag.following_schedule(execution_date) }}"',
dag=dag,
)
Идеально подходит для простых звонков, как этот. И это некоторые другие объекты, напрямую доступные как макросы (например, task
, task_instance
и т.д.); даже некоторые стандартные модули доступны (например, macros.time
,...).