BigQuery support the following polices:
WRITE_APPEND
- Specifies that rows may be appended to an existing table.
WRITE_EMPTY
- Specifies that the output table must be empty.
WRITE_TRUNCATE
- Specifies that write should replace a table.
None of them fits for the purpose of UPSERT
operation.
I'm importing orders Json file to Google Storage and I want to load it into BigQuery. As logic suggests some records will be new while others already exists from previous loads and need to be update (for example update orders status (new /on hold / sent / refund etc...)
I'm using Airflow but my question is generic:
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
)
This code uses the WRITE_TRUNCATE
which means that it delete the whole table and load the requested file.
How can I modify it to support UPSERT
?
Does my only option is to query the table search for existed orders that appear in the json delete them and then perform the LOAD
?
Instead of running a GoogleCloudStorageToBigQueryOperator
, you could run a query that would give you the same result as an upsert.
Example from 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)
This query will:
UPDATE
on that row.INSERT
that new row.Now, how will BigQuery know about your table S
? You can either:
GoogleCloudStorageToBigQueryOperator
.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With