如何将参数传递给数据流模板以进行管道构建

时间:2018-05-10 10:53:11

标签: python-2.7 google-cloud-datastore google-cloud-dataflow

我正在尝试像这样example创建一个祖先查询并将其转移到模板版本。

问题是参数ancestor_id是管道构造期间的函数make_query。 如果我在创建和暂存模板时没有通过它,我将得到 RuntimeValueProviderError:RuntimeValueProvider(选项:ancestor_id,type:int).get()未从运行时上下文中调用。但是如果我在创建模板时传递它,它似乎是一个StaticValueProvider,当我执行模板时它永远不会改变。

将参数传递给模板进行管道构建的正确方法是什么?

import apache_beam as beam
from apache_beam.io.gcp.datastore.v1.datastoreio import ReadFromDatastore
from apache_beam.options.pipeline_options import PipelineOptions
from google.cloud.proto.datastore.v1 import entity_pb2
from google.cloud.proto.datastore.v1 import query_pb2
from googledatastore import helper as datastore_helper
from googledatastore import PropertyFilter

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

def make_query(ancestor_id):
    ancestor = entity_pb2.Key()
    datastore_helper.add_key_path(ancestor, KIND, ancestor_id)
    query = query_pb2.Query()
    datastore_helper.set_kind(query, KIND)
    datastore_helper.set_property_filter(query.filter, '__key__', PropertyFilter.HAS_ANCESTOR, ancestor)
    return query

pipeline_options = PipelineOptions()
test_options = pipeline_options.view_as(TestOptions)
with beam.Pipeline(options=pipline_options) as p:
  entities = p | ReadFromDatastore(PROJECT_ID, make_query(test_options.ancestor_id.get()))

1 个答案:

答案 0 :(得分:1)

两个问题。

  1. ValueProvider.value.get()方法只能在ParDo.process()等运行时方法中运行。请参阅example

  2. 此外,您面临的挑战是您使用的是Google Cloud Datastore IO(来自数据存储区的查询)。截至今日(2018年5月), official documentation表示数据存储IO NOT 尚未接受运行时模板参数。

  3. 对于python,尤其是

      
        

    以下连接器接受运行时参数。       基于文件的IO:textio,avroio,tfrecordio

      

    解决方法:您可能首先运行不带任何模板化参数的查询来获取实体的PCollection。目前,由于任何变换器都可以接受模板化参数,因此您可以将其用作过滤器。但这取决于您的使用案例,可能不适用于您。