Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 谷歌数据流:插入+;在流式管道中的BigQuery中更新_Python_Google Bigquery_Google Cloud Dataflow_Apache Beam - Fatal编程技术网

Python 谷歌数据流:插入+;在流式管道中的BigQuery中更新

Python 谷歌数据流:插入+;在流式管道中的BigQuery中更新,python,google-bigquery,google-cloud-dataflow,apache-beam,Python,Google Bigquery,Google Cloud Dataflow,Apache Beam,主要对象 一个python流式管道,在其中我从pub/sub读取输入 分析输入后,有两个选项可用: 如果x=1->插入 如果x=2->更新 测试 这不能使用ApacheBeam函数来完成,因此您需要使用BigQuery的0.25API来开发它(目前这是Google Dataflow支持的版本) 问题 插入的记录仍在BigQuery缓冲区中,因此update语句失败: UPDATE or DELETE statement over table table would aff

主要对象

一个python流式管道,在其中我从pub/sub读取输入

分析输入后,有两个选项可用:

  • 如果x=1->插入
  • 如果x=2->更新

测试

  • 这不能使用ApacheBeam函数来完成,因此您需要使用BigQuery的0.25API来开发它(目前这是Google Dataflow支持的版本)

问题

  • 插入的记录仍在BigQuery缓冲区中,因此update语句失败:

         UPDATE or DELETE statement over table table would affect rows in the streaming buffer, which is not supported
    

代码

插入

更新


即使该行不在流式缓冲区中,在BigQuery中这仍然不是解决此问题的方法。BigQuery存储更适合批量突变,而不是通过
UPDATE
这样突变单个实体。您的模式与我期望从事务性而非分析性用例中得到的东西是一致的

为此,考虑一种基于追加的模式。每次处理实体消息时,通过流式插入将其写入BigQuery。然后,当需要时,您可以通过查询获得所有实体的最新版本

例如,让我们假设一个任意模式:
idfield
是唯一的实体键/标识符,
message\u time
表示消息发出的时间。您的实体可能有许多其他字段。要获取实体的最新版本,我们可以运行以下查询(并可能将其写入另一个表):


这种方法的另一个优点是,它还允许您在任意时间点执行分析。要在一小时前对实体的状态执行分析,只需添加WHERE子句:
WHERE message\u time,即使该行不在流式缓冲区中,这仍然不是BigQuery中解决此问题的方法。BigQuery存储更适合批量突变,而不是通过
UPDATE
这样突变单个实体。您的模式与我期望从事务性而非分析性用例中得到的东西是一致的

为此,考虑一种基于追加的模式。每次处理实体消息时,通过流式插入将其写入BigQuery。然后,当需要时,您可以通过查询获得所有实体的最新版本

例如,让我们假设一个任意模式:
idfield
是唯一的实体键/标识符,
message\u time
表示消息发出的时间。您的实体可能有许多其他字段。要获取实体的最新版本,我们可以运行以下查询(并可能将其写入另一个表):

这种方法的另一个优点是,它还允许您在任意时间点执行分析。要在一小时前对实体的状态执行分析,只需添加WHERE子句:
WHERE message\u time
def insertCanonicalBQ(input):
    from google.cloud import bigquery
    client = bigquery.Client(project='project')
    dataset = client.dataset('dataset')
    table = dataset.table('table' )
    table.reload()
    table.insert_data(
        rows=[[values]])
def UpdateBQ(input):
    from google.cloud import bigquery
    import uuid
    import time
    client = bigquery.Client()
    STD= "#standardSQL"
    QUERY= STD + "\n" + """UPDATE table SET field1 = 'XXX' WHERE field2=  'YYY'"""
    client.use_legacy_sql = False    
    query_job = client.run_async_query(query=QUERY, job_name='temp-query-job_{}'.format(uuid.uuid4()))  # API request
    query_job.begin()
    while True:
         query_job.reload()  # Refreshes the state via a GET request.
         if query_job.state == 'DONE':
             if query_job.error_result:
                 raise RuntimeError(query_job.errors)
             print "done"
             return input
             time.sleep(1)
#standardSQL
SELECT
  idfield,
  ARRAY_AGG(
    t ORDER BY message_time DESC LIMIT 1
  )[OFFSET(0)].* EXCEPT (idfield)
FROM `myproject.mydata.mytable` AS t
GROUP BY idfield