我最近使用了一些气流,现在我的dag已启动并运行,我已经在UI的“数据分析”部分中查看了一些数据。 制作了一些图表,一些表充满了数据。 我希望能够每周一次通过电子邮件向我发送这些图表和数据,这样我就可以对自己的不同dag运行和任务进行一些定期的全局更新,而不仅仅是每次运行结束时都显示成功或失败的电子邮件。
有什么方便的方法吗?还是我必须使用jinja模板电子邮件操作符和可怕的SQLAlchemy语法来构建自定义dag,以从数据库中重新提取数据?
答案 0 :(得分:1)
据我所知,没有什么“开箱即用”的功能可以满足您的需求;您可能对问题的“我必须建立一个自定义dag […]”部分是正确的。幸运的是,由于您是 Airflow,您可以利用其代码库来提供帮助:
from airflow import models, settings
def python_task(**context):
chart_label = context.params["chart_label"]
query_filters = [models.Chart.label == chart_label]
session = settings.Session()
chart_object = session.query(models.Chart).filter(*query_filters).first()
[...] build and send the email [...]
您可能希望查看Airflow源代码,特别是电子邮件处理部分和界面呈现。请注意,如果您可以使任务相对抽象,则可以很容易地重用它。
答案 1 :(得分:0)
所以我找到了某种解决方案。如果有更好的方法,请随时评论我的工作方式。我很高兴来到这里
我创建了一个静态函数来从图表中恢复数据:
from airflow import settings
def get_data_profilling_data( chart_label):
"""
Get an array containing data from a data profilling chart.
Args:
chart_label: a string that is the name of a an available chart in Data Profiling section.
session(None, optional): Not in use.
Returns:
A list of tuple with first element representing the header of column.
"""
import logging
query_filters = [models.Chart.label == chart_label]
session = settings.Session()
# Query database to get a chart object.
chart_object = session.query(models.Chart).filter(*query_filters).first()
# Replace useless caracter in query and replace % by %% so it's not interpreted by SQLAlchemy
# Also add a ; at the end of the statement.
sql="{}{}".format(chart_object.sql.replace('\n', ' ').replace('\r',' ').replace('%','%%'), ';')
query = session.connection().engine.execute(sql)
#recover sql request header.
headers = tuple(query.keys())
#recover all data
data = query.fetchall()
#close database connection
#session.connection().close()
# Add headers to first position in the list
data.insert(0,headers)
return data
一旦将其提取,我就使用jinja模板:
jinja_str = """<!DOCTYPE html>
<html>
<head>
{% if title %}
<title>{{ title }}</title>
{% else %}
<title>Airflow reports</title>
{% endif %}
</head>
<body>
<table>
{% if rows %}
{% for row in rows %}
{% if loop.index == 1 %}
<!-- table header -->
<tr>{% for elem in row %}
<th>{{ elem }}</th>
{% endfor %}</tr>
{% endif %}
{% if loop.index > 1 %}
<tr>{% for elem in row %}
<td>{{ elem }}</td>
{% endfor %}</tr>
{% endif %}
{% endfor %}
{% endif %}
</table>
</body>
</html>"""
def format_data_from_chart(chart, **kwargs):
data = DagStatic.get_data_profilling_data(chart)
report_template = Template( jinja_str )
report_html = report_template.render({"title": chart,"rows":data})
kwargs["ti"].xcom_push(key='report_html', value=report_html)
这会将使用jinja模板渲染的图表的数据结果推送到xcom中。 现在,我可以使用电子邮件操作员发送邮件了:
send_report= email_task = EmailOperator(
to='you.mail@mail.com',
task_id='send_report',
subject='Airflow HTML report start_date {{ ds }}',
html_content="{{ ti.xcom_pull(key='report_html') }}",
dag=dag)
希望这会对您有所帮助。如果有更好的方法,请随时评论我的工作方式。我很高兴来到这里