BigQuery支持以下策略:
WRITE_APPEND
-指定可以将行追加到现有表中。
WRITE_EMPTY
-指定输出表必须为空。
WRITE_TRUNCATE
-指定写入应替换表。
它们都不适合UPSERT
操作的目的。
我正在将订单Json文件导入Google Storage,并希望将其加载到BigQuery中。逻辑表明,某些记录将是新记录,而其他记录已从以前的加载中获取,并且需要更新(例如,更新订单状态(新的/处于保留状态/已发送/退款等...)
我正在使用Airflow,但我的问题很普遍:
update_bigquery = GoogleCloudStorageToBigQueryOperator(
dag=dag,
task_id='load_orders_to_BigQuery',
bucket=GCS_BUCKET_ID,
destination_project_dataset_table=table_name_template,
source_format='NEWLINE_DELIMITED_JSON',
source_objects=[gcs_export_uri_template],
schema_fields=dc(),
create_disposition='CREATE_IF_NEEDED',
write_disposition='WRITE_TRUNCATE',
skip_leading_rows = 1,
google_cloud_storage_conn_id=CONNECTION_ID,
bigquery_conn_id=CONNECTION_ID
)
此代码使用WRITE_TRUNCATE
,这意味着它将删除整个表并加载请求的文件。
如何修改它以支持UPSERT
?
我唯一的选择是查询表搜索以找到json中显示的现有订单并将其删除,然后执行LOAD
吗?
答案 0 :(得分:3)
您可以运行查询来获得与ups相同的结果,而不是运行GoogleCloudStorageToBigQueryOperator
。
来自https://cloud.google.com/bigquery/docs/reference/standard-sql/dml-syntax#merge_statement的示例:
MERGE dataset.Inventory T
USING dataset.NewArrivals S
ON T.product = S.product
WHEN MATCHED THEN
UPDATE SET quantity = T.quantity + S.quantity
WHEN NOT MATCHED THEN
INSERT (product, quantity) VALUES(product, quantity)
此查询将:
UPDATE
。INSERT
插入该新行。现在,BigQuery将如何知道您的表S
?您可以:
GoogleCloudStorageToBigQueryOperator
将其加载到BQ中的另一个表中。答案 1 :(得分:0)
MERGE
目前尚不支持DELETE+INSERT *'
。如果您想加注星标,则G'问题跟踪器中有一个功能请求。
我们也使用AF并加载订单;-)。因为我们想保留历史更改,所以我们将其加载到一个表中,然后基于主键字段运行deDup查询。 结果保存在单独的表中(被截断)。 该表具有订单行的最新版本/状态,然后我们将其用于后续查询。
查找重复数据并查找ROW_NUM()
,查找SQL示例。
请注意,根据数量的不同,您可能不需要实现,视图或子查询可能同样有效。