Python 如何在Airflow operator中打印唯一消息?
在airflow中,可以使用简单的Python 如何在Airflow operator中打印唯一消息?,python,airflow,Python,Airflow,在airflow中,可以使用简单的print()或建议的记录器写入日志 但是,当试图在操作员内部打印时,这将不起作用 我有以下代码: for i in range(5, 0, -1): gcs_export_uri_template = ["adstest/{{ macros.ds_format(macros.ds_add(ds, -params.i), '%Y-%m-%d', '%Y/%m/%d') }}/*"] update_bigquery = GoogleCloudSto
print()
或建议的记录器写入日志
但是,当试图在操作员内部打印时,这将不起作用
我有以下代码:
for i in range(5, 0, -1):
gcs_export_uri_template = ["adstest/{{ macros.ds_format(macros.ds_add(ds, -params.i), '%Y-%m-%d', '%Y/%m/%d') }}/*"]
update_bigquery = GoogleCloudStorageToBigQueryOperator(
dag=dag,
task_id='load_ads_to_BigQuery-{}'.format(i),
bucket=GCS_BUCKET_ID,
destination_project_dataset_table=table_name_template,
source_format='CSV',
source_objects=gcs_export_uri_template,
schema_fields=dc(),
params={'i': i},
create_disposition='CREATE_IF_NEEDED',
write_disposition='WRITE_APPEND',
skip_leading_rows=1,
google_cloud_storage_conn_id=CONNECTION_ID,
bigquery_conn_id=CONNECTION_ID
)
现在,假设我想打印“我的名字是load\u ads\u to\u BigQuery-{}”。格式{I)
如您所见,此打印是每个操作员的唯一打印
如果我这样做:
for i in range(5, 0, -1):
print("My name is load_ads_to_BigQuery-{}".format{i))
gcs_export_uri_template = ...
update_bigquery = GoogleCloudStorageToBigQueryOperator(...)
所有5个操作员将打印所有5个打印。这在我的情况下是不正确的。
打印内容必须位于Google CloudStorageToBigQueryOperator内
我该怎么做呢?一个可能足够的解决方案是创建一个包装类。示例:
class MyGoogleCloudStorageToBigQueryOperator(BaseOperator):
template_fields = ('bucket', 'source_objects',
'schema_object', 'destination_project_dataset_table')
@apply_defaults
def __init__(self,
bucket,
destination_project_dataset_table,
source_format,
source_objects,
schema_fields,
params,
create_disposition,
write_disposition,
skip_leading_rows,
google_cloud_storage_conn_id,
bigquery_conn_id,
*args,
**kwargs):
super(InfogroupFilestreamOperator, self).__init__(*args, **kwargs)
self.bucket= bucket
self.destination_project_dataset_table=destination_project_dataset_table
...
def execute(self, context):
self.log.info("My name is %s", self.task_id)
hook=GoogleCloudStorageToBigQueryOperator(
task_id="doesnt_matter",
bucket=self.bucket,
source_format=self.source_format,
...
)
return hook.execute(context)
MyGoogleCloudStorageToBigQueryOperator
然后可以在for循环中实例化,而不是GoogleCloudStorageToBigQueryOperator
。基于@judoole的答案,您可以直接扩展GoogleCloudStorageToBigQueryOperator
class MyGoogleCloudStorageToBigQueryOperator(LoggingMixin, GoogleCloudStorageToBigQueryOperator):
def execute(self, context):
self.logger.info('Inside task {task_id}'.format(task_id=context['task_id']))
super().execute(context)
更一般地说,您可以编写一个mixin类,该类将自动为各种操作符执行这种类型的日志记录
class LogTaskExecutionMixin(object):
def execute(self, context):
self.logger.info('Inside task {task_id}'.format(task_id=context['task_id']))
super().execute(context)
class MyGoogleCloudStorageToBigQueryOperator(
LogTaskExecutionMixin, LoggingMixin, GoogleCloudStorageToBigQueryOperator
):
pass
这两种方法的思想都是定义一个新的运算符,该运算符在执行前写入日志消息,但在其他方面与扩展的运算符相同。您也可以使用BaseOperator的log方法在运算符内部登录,如so
self.log.info(“这是%s”,“有趣”)
。所有的打印语句都是在dag内完成的,还是for循环在自定义运算符内完成的?@judoole我不确定我是否理解您是在dag文件内打印的,还是在自建模块内打印的,在for循环中创建5GoogleCloudStorageToBigQueryOperator
s?很抱歉,我没有回复。@judoole根本不打印。我想将打印添加到我的代码中。我想在GoogleCloudStorageToBigQueryOperator中打印。我认为这对所有操作员来说都是一个问题。你建议我用一个函数包装我的操作员,该函数将打印并执行操作员。我不认为我支持这一点:\n我提交了一张罚单为什么不支持类MyGoogleCloudStorageToBigQueryOperator(GoogleCloudStorageToBigQueryOperator):传递,重写执行,并调用super()。执行(上下文)
?是的,我想这在这种情况下也同样有效。更好的解决方案。如果您想获得额外的分数,请随意编辑,或者自己回答。我会投赞成票。