【问题标题】:How to export a null field on BIGQUERY如何在 BIGQUERY 上导出空字段
【发布时间】:2021-10-21 11:08:52
【问题描述】:

当我尝试通过 BigQuery 导出 JSON 对象时,当存在具有“null”值的字段时,它会从结果下载中消失。

下载查询示例:

EXPORT DATA OPTIONS(
  uri='gs://analytics-export/_*',
  format='JSON',
  overwrite=true) AS


SELECT NULL AS field1  

实际结果是:{}

当预期结果为:{field1: null}

如何像我在预期结果中显示的那样强制使用 null 值导出?

【问题讨论】:

  • 试试SELECT 'null' as field1

标签: google-bigquery bigquery-udf


【解决方案1】:

对于这个 OP,你可以使用:

Select TO_JSON_STRING(NULL) as field1
Select 'null' as field1

Export DATA documentation 上,没有提到在输出中包含空值的选项,因此我认为您可以转到feature request 报告页面并为其创建一个请求。另外,在其他项目上也有类似的观察,以及暂时不支持的点,详情见here

有很多解决方法,让我向您展示 2 个选项,见下文:

选项 1:使用 bigquery 客户端库直接从 python 调用

from google.cloud import bigquery
import json

client = bigquery.Client()

query = "select null as field1, null as field2"
query_job = client.query(query)

json_list = {}
for row in query_job:
    json_row = {'field1':row[0],'field2':row[1]}
    json_list.update(json_row)
    
with open('test.json','w+') as file:
    file.write(json.dumps(json_list))

选项 2:将 apache beam 数据流与 python 和 BigQuery 结合使用以产生理想的输出

import argparse
import re
import json

import apache_beam as beam
from apache_beam.io import BigQuerySource
from apache_beam.io import WriteToText
from apache_beam.options.pipeline_options import PipelineOptions
from apache_beam.options.pipeline_options import SetupOptions



def add_null_field(row, field):
  if field!='skip':
    row.update({field: row.get(field, None)})
  return row


def run(argv=None, save_main_session=True):
    parser = argparse.ArgumentParser()
    parser.add_argument(
        '--output',
        dest='output',
        required=True,
        help='Output file to write results to.')
    known_args, pipeline_args = parser.parse_known_args(argv)

    pipeline_options = PipelineOptions(pipeline_args)
    pipeline_options.view_as(SetupOptions).save_main_session = save_main_session

    with beam.Pipeline(options=pipeline_options) as p:

        (p
        | beam.io.Read(beam.io.BigQuerySource(query='SELECT null as field1, null as field2'))
        | beam.Map(add_null_field, field='skip')
        | beam.Map(json.dumps)
        | beam.io.Write(beam.io.WriteToText(known_args.output, file_name_suffix='.json')))

if __name__ == '__main__': 
  run()

运行它:

python -m export --output gs://my_bucket_id/output/ \
                 --runner DataflowRunner \
                 --project my_project_id \
                 --region my_region \
                 --temp_location gs://my_bucket_id/tmp/

Note: Just replace my_project_id,my_bucket_id and my_region with the appropriate values. Look on your cloud storage bucket for output file.

这两个选项都会为您生成您正在寻找的输出:

{"field1": null, "field2": null}

如果它对您有帮助并给您想要达到的结果,请告诉我。

【讨论】:

  • 谢谢,我已经改变了输出模式,这个问题不再发生了。我们没有在我们的项目中使用 Appache Beam,尽管它是一个不错的选择
猜你喜欢
  • 2022-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-06
  • 1970-01-01
相关资源
最近更新 更多