[英]datetime.now() function generate time every 5 milisecods in Python
[英]How to generate datetime.now() in airflow exactly one time
当我尝试根据name + current date
生成唯一名称时出现错误。
NAME = 'name-{timestamp}'.format(timestamp=datetime.now())
但是每个任务实例再次生成datetime.now()
并且每个任务的NAME
变得不同。
task1 = CustomOperator(
task_id='task-1',
name = NAME,
...
)
task2 = CustomOperator(
task_id='task-2',
name = NAME,
...
)
task1
和task2
里面的NAME
会不同。 我需要NAME
是唯一的,并且可以从 DAG 中的任务实例进行全局访问。 有什么建议?
气流任务预计是静态的或缓慢变化的。 Airflow 每隔min_file_process_interval
(默认 30 秒)解析 DAG 文件 - 这意味着每 30 秒您将创建一个新任务 - 甚至可能不会运行。
很难理解为什么要创建这样的任务,因为您没有解释您的用例,但是如果您需要动态任务,您可以这样做:
for i in range(0, 5):
DummyOperator(task_id='{0}'.format(i))
编辑:现在您编辑了您的问题并进行了更好的解释。 name 参数是您的 Operator 的一些自定义参数。 它可以是任何你想要的。 你可以做什么:
timestamp = datetime.now()
for i in range(1, 3):
task_id = f'task_{i}'
CustomOperator(task_id=task_id, name=f'{task_id}_{str(timestamp)}')
请注意,虽然这将为您提供独特的值,但您很难跟踪它们。 一种更好、更 Airflowy 的方法是使用{{ execution_date }}
,它假设name
是模板化字段:
for i in range(1, 3):
task_id = f'task_{i}'
CustomOperator(task_id=task_id, name=f'{task_id}_{{{{ execution_date }}}}')
或者您可以使用{{ task_instance_key_str }}
宏,它是格式为{dag_id}__{task_id}__{ds_nodash}
的任务实例的唯一的、人类可读的键
for i in range(1, 3):
task_id = f'task_{i}'
CustomOperator(task_id=task_id, name='{{ task_instance_key_str }}')
正如Elad和其他评论者所建议的那样,您可能不想要这个。 也许您应该在execute
方法中生成和记录/发出此信息。
尽管如此,对于跨不同领域、任务和编程语言的编程新手来说,这是一个非常常见的“陷阱”,因此我认为如果仅出于教学目的,这里展示该模式是值得的。
答案很简单:计算一次的时间,并将其保存在一个变量。 就是这样。 就这么简单。 这实际上就是变量的用途。
我还强烈建议使用datetime.strftime
方法显式格式化时间戳,而不是依赖str()
为您隐式地完成它。 盲目str
-ifying东西是另一个经典的新手的错误。
最后,使用时区感知 datetimes ,并使用 UTC 。 不要想太多。 去做就对了。 以后你会感谢我的。
完整示例:
from __future__ import annotations
import sys
from datetime import datetime, timezone
from typing import Any
if sys.version_info < (3, 9):
from typing import Dict
else:
Dict = dict
from airflow import DAG
from airflow.models.baseoperator import BaseOperator
# Define a custom operator
class MyOperator(BaseOperator):
"""A custom Airflow operator that doesn't really do anything."""
def __init__(self, task_id: str, name: str, **kwargs) -> None:
self.task_id = task_id
self.name = name
super().__init__(**kwargs)
def execute(self, context: Dict[str, Any]) -> int:
print(
f'Hello, I am {self.name}, '
f'and I am executing Task ID {self.task_id}.'
)
return len(context)
# Pre-compute the time, making sure to use UTC.
now = datetime.now(timezone.utc)
# Format the time, unambiguously.
now_fmt = now.strftime('%Y-%m-%d_%H:%M:%S%z')
# Another option for formatting.
# See:
# * https://docs.python.org/3/library/datetime.html#datetime.datetime.isoformat
# * https://en.wikipedia.org/wiki/ISO_8601
# * https://datatracker.ietf.org/doc/html/rfc3339
# now_fmt = now.isoformat()
# Use the formatted time string as many times as you need.
with DAG(...) as dag:
task1 = MyOperator(
task_id='task-1',
name = f'task-1_{now_fmt}',
...
)
task2 = MyOperator(
task_id='task-2',
name = f'task-2_{now_fmt},
...
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.