[英]S3KeySensor in Airflow 2
我有一個名為my_dag.py
的 dag,它利用 Airflow 2 中的 S3KeySensor 來檢查是否存在 s3 密鑰。 當我直接在 dag 內部使用傳感器時,它起作用了:
with TaskGroup('check_exists') as check_exists:
path = 's3://my-bucket/data/my_file'
poke_interval = 30
timeout = 60*60
mode = 'reschedule'
dependency_name = 'my_file'
S3KeySensor(
task_id = 'check_' + dependency_name + '_exists',
bucket_key = path,
poke_interval = poke_interval,
timeout = timeout,
mode = mode
)
上面的日志看起來像:
[2022-05-03, 19:51:26 UTC] {s3.py:105} INFO - Poking for key : s3://my-bucket/data/my_file
[2022-05-03, 19:51:26 UTC] {base_aws.py:90} INFO - Retrieving region_name from Connection.extra_config['region_name']
[2022-05-03, 19:51:27 UTC] {taskinstance.py:1701} INFO - Rescheduling task, marking task as UP_FOR_RESCHEDULE
這是對的。 預計會重新安排,因為該文件尚不存在。
但是,我想檢查其他 dag 中的任意數量的路徑,因此我將傳感器移動到另一個名為 helpers.py 的文件中名為test
的helpers.py
中。 我在調用test
的任務組中的my_dag.py
中使用 python 運算符。 它看起來像這樣:
with TaskGroup('check_exists') as check_exists:
path = 's3://my-bucket/data/my_file'
dependency_name = 'my_file'
wait_for_dependencies = PythonOperator(
task_id = 'wait_for_my_file',
python_callable = test,
op_kwargs = {
'dependency_name': dependency_name,
'path': path
},
dag = dag
)
wait_for_dependencies
helpers.py 中的helpers.py
test
如下所示:
def test(dependency_name, path, poke_interval = 30, timeout = 60 * 60, mode = 'reschedule'):
S3KeySensor(
task_id = 'check_' + dependency_name + '_exists',
bucket_key = path,
poke_interval = poke_interval,
timeout = timeout,
mode = mode
)
但是,當我運行 dag 時,即使該文件不存在,該步驟也被標記為成功。 日志顯示:
[2022-05-03, 20:07:54 UTC] {python.py:175} INFO - Done. Returned value was: None
[2022-05-03, 20:07:54 UTC] {taskinstance.py:1282} INFO - Marking task as SUCCESS.
似乎 airflow 不喜歡通過 python 操作員使用傳感器。 這是真的? 還是我做錯了什么?
我的目標是遍歷多條路徑並檢查每條路徑是否存在。 但是,我在其他 dag 中這樣做,這就是為什么我將傳感器放在另一個文件中的 function 中。
如果有其他想法可以做到這一點,我很開放!
謝謝你的幫助!
這不會像您預期的那樣工作。 您創建了一個運算符內部運算符的案例。 有關這意味着什么的信息,請參閱此答案。
在您的情況下,您使用PythonOperator
S3KeySensor
這意味着當PythonOperator
運行時,它只執行 S3KeySensor 的 init S3KeySensor
- 它不會調用運算符本身的邏輯。 在運算符內部使用運算符是一種不好的做法。
當您嘗試在操作員內部使用傳感器時,您的情況更加極端。 傳感器需要為每個戳周期調用poke()
function。 為簡化起見 - 當您像設置它們時那樣設置mode = 'reschedule'
時,您無法享受 Sensor 的強大功能,因為 reschedule 意味着如果條件尚未滿足,您想要釋放工作人員,但PythonOperator
不知道該怎么做.
如何解決您的問題:
選項1:
從您展示的代碼中,您可以簡單地執行以下操作:
with TaskGroup('check_exists') as check_exists:
path = 's3://my-bucket/data/my_file'
dependency_name = 'my_file'
S3KeySensor(
task_id='check_' + dependency_name + '_exists',
bucket_key=path,
poke_interval=30,
timeout=60 * 60,
mode='reschedule'
)
我沒有看到為什么這對你不起作用的原因。
選項 2:
如果由於某種原因選項 1 對您不利,則創建一個自定義傳感器,該傳感器也接受dependency_name
和path
,並像任何其他運算符一樣使用它。 我沒有測試它,但像下面這樣的東西應該可以工作:
class MyS3KeySensor(S3KeySensor):
def __init__(
self,
*,
dependency_name:str = None,
path: str = None,
**kwargs,
):
super().__init__(**kwargs)
self.task_id = task_id = 'check_' + dependency_name + '_exists'
self.bucket_name = path
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.