我有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))
,但连续两次运行包含完全相同的过滤器。
答案 0 :(得分:2)
您所使用的来源需要价值提供者的支持。只有在适当的时候才能打开包装。
创建自己的源代码时,您显然可以完全控制它。使用现有资源时,我只会看到两个选项: