简体   繁体   English

如何根据从 Prefect 2.0 的 Prefect 流程中传递的变量动态重命名任务运行?

[英]How to dynamically rename a task run based on passed variable from within a Prefect flow for Prefect 2.0?

I have a prefect task that will source a table by name from a database as below.我有一个完美的任务,它将按名称从数据库中获取一个表,如下所示。 What I would like to do is to have the task run name include the source table variable so that I can easily keep track of it from the Prefect Cloud UI (when I source 10+ tables in the one flow).我想要做的是让任务运行名称包含源表变量,以便我可以轻松地从 Prefect Cloud UI 跟踪它(当我在一个流程中获取 10 多个表时)。

@task
def source_table_by_name(id, table_name):
    logger = get_run_logger()

    sql = f"SELECT * FROM {table_name} WHERE upload_id = '{id}'"
    df = pd.read_sql(sql, sd_engine_prod)

    logger.info(f"Source table {table_name} from database")
    return df

What I tried to do initially was put a template in the name to be able to reference the variables passed (I'll be honest, ChatGPT hallucinated this one for me).我最初尝试做的是在名称中放置一个模板,以便能够引用传递的变量(老实说,ChatGPT 让我产生了这个幻觉)。

@task(name='source_table_by_name_{table_name}')
def source_table_by_name(id, table_name):
    logger = get_run_logger()

    sql = f"SELECT * FROM {table_name} WHERE upload_id = '{id}'"
    df = pd.read_sql(sql, sd_engine_prod)

    logger.info(f"Source table {table_name} from database")
    return df


@flow
def report_flow(upload_id):
    df_table1 = source_table_by_name(upload_id, table1)
    df_table2 = source_table_by_name(upload_id, table2)

I am able to just write a specific task for each table to be sourced so the naming is fixed but clear from the start.我可以为每个要获取的表编写一个特定的任务,这样命名是固定的,但从一开始就很清楚。 However it would be great to have a more DRY approach if possible.但是,如果可能的话,采用更 DRY 的方法会很棒。

Totally justifiable question, we have an internal WIP to address the issue in a better way and there is also this open issue but for now you could use with_options() and pass the variable through a for loop:完全合理的问题,我们有一个内部 WIP 可以更好地解决这个问题,还有这个未解决的问题,但现在您可以使用with_options()并通过 for 循环传递变量:

from prefect import flow, task
from typing import List
import time


@task
def hello_world(user: str) -> None:
    print(f"✨ Hello from Prefect, {user}! 👋 📚")
    time.sleep(5)


@flow(log_prints=True)
def hi(
    users: List[str] = [
        "Marvin",
        "Anna",
        "Prefect"
    ]
) -> None:
    for user in users:
        hello_world.with_options(name=user).submit(user)


if __name__ == "__main__":
    hi()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM