在Dataflow中使用模板化参数构建动态数据存储区查询

时间:2019-07-18 06:37:19

标签: python google-cloud-datastore google-cloud-dataflow apache-beam

我有Apache Beam管道,可从Google Cloud Datastore读取数据。管道以批处理模式在Google Cloud Dataflow中运行,并且是用Python编写的。

问题与模板化参数有关,我正尝试使用该参数创建带有动态时间戳过滤器的数据存储区查询。

管道定义如下:

import apache_beam as beam
from apache_beam.options.pipeline_options import PipelineOptions
from apache_beam.io.gcp.datastore.v1new.datastoreio import ReadFromDatastore
from apache_beam.io.gcp.datastore.v1new.types import Query

class UserOptions(PipelineOptions):
    @classmethod
    def _add_argparse_args(cls, parser):
        parser.add_value_provider_argument('--filter', type=int)

pipeline_options = PipelineOptions()

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

    user_options = pipeline_options.view_as(UserOptions)

    data = (p
        | 'Read' >> ReadFromDatastore(build_query(user_options.filter.get()))
        | ...

build_query的功能如下:

def build_query(filter):
    return Query(
        kind='Kind',
        filters=[('timestamp', '>', filter)],
        project='Project'
    )

运行此命令将导致错误RuntimeValueProvider(...).get() not called from a runtime context

我也尝试过ReadFromDatastore(build_query(user_options.filter)),但是错误是ValueError: (u"Unknown protobuf attr type [while running 'Read/Read']", <class 'apache_beam.options.value_provider.RuntimeValueProvider'>)

如果从等式中删除模板化参数,则一切工作都很好。像这样:ReadFromDatastore(build_query(1563276063))。因此,问题在于在构建数据存储区查询时使用模板化参数。

我的猜测是build_query应该用其他方式定义,但是在花了一些时间编写文档并进行谷歌搜索之后,我仍然不知道该怎么做。

任何有关如何解决此问题的建议都将受到赞赏!

编辑1

实际上,在这种情况下,过滤器始终是相对于当前时间戳的,因此,如果还有其他使用动态值的方法,可能甚至没有必要将其作为参数传递。尝试过ReadFromDatastore(build_query(int(time())-90000)),但连续两次运行包含完全相同的过滤器。

1 个答案:

答案 0 :(得分:2)

您所使用的来源需要价值提供者的支持。只有在适当的时候才能打开包装。

创建自己的源代码时,您显然可以完全控制它。使用现有资源时,我只会看到两个选项:

  1. 在创建模板时提供值,这意味着不要为其使用模板参数
  2. 为现有来源创建PR,以支持模板参数