在 Beam 管道中以编程方式生成 BigQuery 架构

Posted

技术标签:

【中文标题】在 Beam 管道中以编程方式生成 BigQuery 架构【英文标题】:Programmatically generating BigQuery schema in Beam pipeline 【发布时间】:2017-12-04 15:43:23 【问题描述】:

我有一组同质字典,如何在不知道架构的情况下将它们写入 BigQuery?

BigQuerySink 要求我在构建它时指定架构。但是,我不知道架构:它是由我要编写的字典的键定义的。

有没有办法让我的管道推断架构,然后将其返回(作为侧输入?)到接收器?

例如:

# Create a PCollection of dicts, something like
# 'field1': 'myval', 'field2': 10
data = (p | 'generate_data' >> beam.ParDo(CreateData())

# Infer the schema from the data
# Generates a string for each element (ok to assume all dict keys equal)
# "field1:STRING, field2:INTEGER"
schema = (data
  | 'infer_schema' >> beam.ParDo(InferSchema())
  | 'sample_one'   >> beam.combiners.Sample.FixedSizeGlobally(1))

但是,我如何将架构作为参数提供给 BigQuerySink,并在 beam.io.Write 中使用它?

我知道这不正确,但我想做的是:

sink = BigQuerySink(tablename, dataset, project, schema=Materialize(schema))
p | 'write_bigquery' >> beam.io.Write(sink)

tl;博士 有没有办法从 apache Beam 以编程方式从数据中推断架构来创建和编写 bigquery 表?

【问题讨论】:

BigQuery API 具有自动检测架构功能。如果 Beam 不支持此功能,则值得针对 Beam SDK 提出问题。 架构自动检测的文档位于cloud.google.com/bigquery/docs/schema-detect 谢谢蒂姆。 Unf,当前如果表不存在,API 会拒绝没有模式的接收器。我会看看我是否能弄清楚在哪里向 Beam 提出功能请求。 【参考方案1】:

假设您的架构可以经常更改,那么将数据保持在更通用的形式可能会更好。

例如,您的行可能包含一条重复的记录(您的字典条目)。

记录架构如下所示: 键(字符串) |可选 string_val (STRING) |可选的 int_val (INTEGER) 可选的 double_val (DOUBLE) |可选 boolean_val (BOOLEAN) | ...

然后您可以编写按类型扫描记录的查询。这有点不太有效(因为如果它们位于不同的列中,您将不得不扫描您可能可以跳过的行),但完全避免了预先指定您的架构。

【讨论】:

【参考方案2】:

目前,我想出的最佳解决方案是明确硬编码 dict 键到 BigQuery 架构的映射。有两个好处 - 它可以解决必须指定模式的问题,它可以让我从 BigQuery 中不想要的 dict 中过滤元素。

SCHEMA = 
  'field1': 'INTEGER',
  'field2': 'STRING',
  ...

schema_str = ','.join(['%s:%s' % (k, v) for k,v in SCHEMA.iteritems()])

sink = BigQuerySink(tablename,
        dataset=dataset,
        project=project,
        schema=schema_str,
        write_disposition=BigQueryDisposition.WRITE_TRUNCATE)

(pipeline
  # filters just the keys of each dict to the keys of SCHEMA.
  | 'filter_fields' >> beam.ParDo(FilterFieldKeysDoFn(SCHEMA))
  | 'to_bigquery' >> beam.io.Write(sink))

【讨论】:

以上是关于在 Beam 管道中以编程方式生成 BigQuery 架构的主要内容,如果未能解决你的问题,请参考以下文章

在 iOS 中以编程方式生成视图

在 CloudFormation 模板中以编程方式生成子网 CIDR 块(或将整数相加)

使用 RemoteView 删除 Widget 中以编程方式生成的布局

JavaFX 中以编程方式生成的 TriangleMesh 的纹理坐标

使用 Apache Beam 向 BigQuery 传播插入时如何指定 insertId

寻找在 xml3d 中以编程方式生成几何图形的示例