[英]How to properly define and use a schema in Apache Beam Python?
以下代码尝试从源读取数据、定义架构并执行 SQLTransform。
...
class RowSchema(typing.NamedTuple):
colA: str
colB: typing.Optional[str]
beam.coders.registry.register_coder(RowSchema, beam.coders.RowCoder)
def run(argv=None):
...
with beam.Pipeline(options=pipeline_options) as p:
query = '''
SELECT
colA, colB
FROM `{}`
''' \
.format(
known_args.table
)
pcol = (p
| 'read from BQ' >>
beam.io.ReadFromBigQuery(
gcs_location=known_args.execution_gcs_location,
query=query,
use_standard_sql=True,
)
| 'ToRow' >> beam.Map(
lambda x: RowSchema(**x)).with_output_types(RowSchema)
| SqlTransform(
"""
...
""")
| beam.Map(print)
)
...
但是,它会导致以下错误:
File "/home/lib/python3.9/site-packages/apache_beam/coders/coders.py", line 423, in encode
return value.encode('utf-8')
AttributeError: 'int' object has no attribute 'encode' [while running 'ToRow']
使用相同的结构,以下管道可以正常工作:
pcol = (p
| "Create" >> beam.Create(
[{'colA': 'a1', 'colB': 'b1'}, {'colA': 'a2', 'colB': None}])
| 'ToRow' >> beam.Map(lambda x: RowSchema(**x)).with_output_types(RowSchema)
| SqlTransform(
"""
...
""")
| beam.Map(print)
)
示例 1 中似乎缺少的是将输入数据转换为beam.pvalue.Row的实例,这是示例 2 中的情况,但示例 1 中没有。
如何将输入转换为 Row 对象以用于 static 架构,假设这确实是问题所在?
bigquery 模块也有内置模式,但仅适用于 BigQuery 写入。
我还检查了示例,包括这个使用不适用于此用例的动态模式的示例。
事实证明,colA 在 BigQuery 中实际上是一个 INTEGER,因此只需在模式定义中将其类型更改为 int 即可解决问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.