如何使用bigquery运算符将查询参数传递到sql文件

时间:2019-05-24 06:35:52

标签: airflow google-cloud-composer

我需要访问sql文件中BigqueryOperator传递的参数,但出现错误ERROR - queryParameters argument must have a type <class 'dict'> not <class 'list'> 我正在使用以下代码:

t2 = bigquery_operator.BigQueryOperator(
task_id='bq_from_source_to_clean',
sql='prepare.sql',
use_legacy_sql=False,
allow_large_results=True,
query_params=[{ 'name': 'threshold_date', 'parameterType': { 'type': 'STRING' },'parameterValue': { 'value': '2020-01-01' } }],
destination_dataset_table="{}.{}.{}".format('xxxx',
                                            'xxxx',
                                            'temp_airflow_test'),
create_disposition="CREATE_IF_NEEDED",
write_disposition="WRITE_TRUNCATE",
dag=dag

Sql:

select  cast(DATE_ADD(a.dt_2, interval 7 day) as DATE) as dt_1
,a.dt_2
,cast('2010-01-01' as DATE) as dt_3 
from (select cast(@threshold_date as date) as dt_2) a

我正在使用Google作曲家版本 composer-1.7.0-airflow-1.10.2

谢谢。

3 个答案:

答案 0 :(得分:1)

深入研究源代码后,似乎BigQueryHook的Airflow 1.10.3中已修复了一个错误。

您定义query_params的方式对于较新版本的Airflow是正确的,根据BigQuery API,它应该是列表:请参见https://cloud.google.com/bigquery/docs/parameterized-queries#bigquery_query_params_named-python

无论如何,您会收到此错误,因为在Airflow 1.10.2中,query_params被定义为dict,请参见:

https://github.com/apache/airflow/blob/1.10.2/airflow/contrib/hooks/bigquery_hook.py#L678

query_param_list = [
    ...
    (query_params, 'queryParameters', None, dict),
    ...
]

这将导致内部_validate_value函数抛出TypeError

https://github.com/apache/airflow/blob/1.10.2/airflow/contrib/hooks/bigquery_hook.py#L1954

def _validate_value(key, value, expected_type):
    """ function to check expected type and raise
    error if type is not correct """
    if not isinstance(value, expected_type):
        raise TypeError("{} argument must have a type {} not {}".format(
            key, expected_type, type(value)))

我在Airflow 1.10.2中没有找到query_params的任何示例(或任何单元测试...),但是我认为这仅仅是因为它不可用。

这些错误已通过以下提交修复:

这些更改已嵌入到Airflow 1.10.3中,但到目前为止,Composer(https://cloud.google.com/composer/docs/concepts/versioning/composer-versions#new_environments)中不提供Airflow 1.10.3:最新版本已于2019年5月16日发布,并嵌入了1.10版.2。

等待这个新版本,我看到2种解决问题的方法:

  • 复制/粘贴BigQueryOperatorBigQueryHook的固定版本,并将其嵌入您的源中以使用它们,或扩展现有的BigQueryHook并覆盖错误的方法。我不确定您可以直接修补BigQueryHook(在Composer环境中无法访问这些文件)
  • 自己对SQL查询进行模板化(而不使用query_params

答案 1 :(得分:1)

这绝对是composer(Airflow 1.10.2)的一个错误,我们通过从github拉下气流文件并修补bigquery_hook.py文件,然后在bigquery_operator.py中引用固定文件(均已上载到lib)来修复它文件夹),修复方法是:

  1. bigquery_operator.py(第21行)

    从lib.bigquery_hook导入BigQueryHook

  2. bigquery_hook.py

    (第678行)(query_params,“ queryParameters”,无,列表)

    (第731行),如果configuration ['query']和configuration ['query'] ['useLegacySql']和\

  3. 中的“ useLegacySql”

然后在您的dag中,引用上传的BQ运算符:“从lib.bigquery_operator import BigQueryOperator导入”

答案 2 :(得分:0)

在BigQuery运算符中共享两种传递查询参数的方式-

  1. Jinja模板化-在以下查询中,您看到'{{(execution_date-macros.timedelta(hours = 1))。strftime('%Y-%m- %d%H:00:00')}}'是吉娜·温特,将在运行时得到解决。

    bigquery-public-data.stackoverflow.posts_questions处选择创建所有者名称,标题,视图数创建日期> CAST(' {{(执行日期-macros.timedelta(hours = 1))。strftime('%Y-%m-%d %H:00:00')}} 'AS TIMESTAMP)ORDER BY view_count DESC LIMIT 100

  2. query_params -对于in子句,类型将是数组,而在数组类型中,type应该是大查询中列​​的类型。

    query_params = [{'name':'DATE_IN_CLAUSE','parameterType':{'type':'ARRAY','arrayType':{'type':'TIMESTAMP'}},'parameterValue':{'arrayValues ':[{'value':datetime.utcnow()。strftime('%Y-%m-%d%H:00:00')},{'value':(datetime.utcnow()-timedelta(hours = 1))。strftime('%Y-%m-%d%H:00:00')}]}}, {'name':'COUNT','parameterType':{'type':'INTEGER'},'parameterValue':{'value':1}}]

    从bigquery-public-data.stackoverflow.posts_questions中的UNNEST(@DATE_IN_CLAUSE)和view_count中选择创建owner_display_name,标题,view_count,然后选择view_count> @COUNT ORDER BY view_count DESC LIMIT 100

注意-上层查询和参数可能不会给您结果,但它们将成功而不会出现任何错误。这些示例仅用于演示如何传递参数。