Представьте себе простой конвейер данных Google. В этом конвейере вы читаете из BQ, используя функцию луча apache, и в зависимости от возвращенного pcollection вы должны обновить эти строки
Journeys = (p
| 'Read from BQ' >> beam.io.Read(
beam.io.BigQuerySource(query=query, dataset="dataset", use_standard_sql=True)))
Update = ( Journeys
| 'Updating Journey Table' >> beam.Map(UpdateBQ))
Write = (Journeys
| 'Write transform to BigQuery' >> WriteToBigQuery('table', TABLE_SCHEMA_CANONICAL))
Проблема этого конвейера состоит в том, что UpdateBQ выполняется для каждого элемента в возвращенной коллекции pcollection при чтении таблицы (beam.Map).
Какой может быть лучший способ выполнить обновление таблицы BigQuery?
Я полагаю, что это можно сделать без использования beam.Map и выполнить только и обновить, которые обрабатывают все входные pcolletion одновременно.
дополнительный
def UpdateBQ(input):
from google.cloud import bigquery
import uuid
import time
client = bigquery.Client()
STD = "#standardSQL"
QUERY = STD + "\n" + """UPDATE table SET Field= 'YYY' WHERE Field2='XXX'"""
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()
<...>
Возможное решение
with beam.Pipeline(options=options) as p:
Journeys = (p
| 'Read from BQ' >> beam.io.Read(
beam.io.BigQuerySource(query=query, dataset="dataset", use_standard_sql=True))
)
Write = (Journeys
| 'Write transform to BigQuery' >> WriteToBigQuery('table', TABLE_SCHEMA_CANONICAL))
UpdateBQ();
Проводите ли вы дальнейшие преобразования, используя трубопровод луча после чтения из BQ? Или это так, как вы показали в коде, то есть читаете из BQ, а затем запускаете команду обновления в BQ? В этом случае вам вообще не нужен луч. Просто используйте запрос BQ для обновления данных в таблице с использованием другой таблицы. Превосходные методы BQ предлагают избежать однострочной вставки/обновления за раз.