Sql BigQuery:使用DML以原子方式替换日期分区
我经常想将一天的数据加载到一个日期分区的BigQuery表中,替换已经存在的任何数据。我知道如何对“旧式”数据分区表(具有Sql BigQuery:使用DML以原子方式替换日期分区,sql,google-bigquery,Sql,Google Bigquery,我经常想将一天的数据加载到一个日期分区的BigQuery表中,替换已经存在的任何数据。我知道如何对“旧式”数据分区表(具有\u PARTITIONTIME字段的表)执行此操作,但不知道如何对新样式的日期分区表执行此操作(这些表使用普通的日期/时间戳列来指定分区,因为它们不允许使用$装饰器) 假设我想在my_table上执行此操作。对于旧式的日期分区表,我使用使用$装饰器和WRITE\u TRUNCATEWRITE处置的加载作业来完成此操作——例如,我将目标表设置为my_table$2018100
\u PARTITIONTIME
字段的表)执行此操作,但不知道如何对新样式的日期分区表执行此操作(这些表使用普通的日期/时间戳列来指定分区,因为它们不允许使用$
装饰器)
假设我想在my_table
上执行此操作。对于旧式的日期分区表,我使用使用$
装饰器和WRITE\u TRUNCATE
WRITE处置的加载作业来完成此操作——例如,我将目标表设置为my_table$20181005
但是,我不知道如何使用DML执行等效的操作。我发现自己在执行单独的DELETE
和INSERT
命令。这并不好,因为它增加了复杂性、查询数量,而且操作不是原子的
我想知道如何使用MERGE
命令来实现这一点,以使所有这些都包含在一个单一的原子操作中。但是,我无法理解MERGE命令的语法,也没有找到此用例的示例。有人知道应该如何实现吗
理想的答案是一个DML语句,它从源表
中选择所有列,并将其插入我的表
的日期分区,删除我的表
的2018-10-05
日期分区中的任何现有数据e
和my_table
具有相同的架构,并且my_table
在day
列上进行分区,该列的类型为DATE
因为他们不允许一个人使用$decorator
但它们确实如此——当您加载到基于列的分区表中时,也可以使用表名$YYYYMMDD
$ bq query --use_legacy_sql=false "CREATE TABLE tmp_elliottb.PartitionedTable (x INT64, y NUMERIC, date DATE) PARTITION BY date"
然后我加载到一个特定的分区:
$ echo "1,3.14,2018-11-07" > row.csv
$ bq load "tmp_elliottb.PartitionedTable\$20181107" ./row.csv
$ echo "2,0.11,2018-11-07" > row.csv
$ bq load --replace "tmp_elliottb.PartitionedTable\$20181107" ./row.csv
我试图将输入数据加载到错误的分区,但收到错误:
$ echo "1,3.14,2018-11-07" > row.csv
$ bq load "tmp_elliottb.PartitionedTable\$20181105" ./row.csv
Some rows belong to different partitions rather than destination partition 20181105
然后,我替换了分区的数据:
$ echo "1,3.14,2018-11-07" > row.csv
$ bq load "tmp_elliottb.PartitionedTable\$20181107" ./row.csv
$ echo "2,0.11,2018-11-07" > row.csv
$ bq load --replace "tmp_elliottb.PartitionedTable\$20181107" ./row.csv
是的,可以使用MERGE
替换分区表分区的数据,但也可以使用加载作业
因为他们不允许一个人使用$decorator
但它们确实如此——当您加载到基于列的分区表中时,也可以使用表名$YYYYMMDD
$ bq query --use_legacy_sql=false "CREATE TABLE tmp_elliottb.PartitionedTable (x INT64, y NUMERIC, date DATE) PARTITION BY date"
然后我加载到一个特定的分区:
$ echo "1,3.14,2018-11-07" > row.csv
$ bq load "tmp_elliottb.PartitionedTable\$20181107" ./row.csv
$ echo "2,0.11,2018-11-07" > row.csv
$ bq load --replace "tmp_elliottb.PartitionedTable\$20181107" ./row.csv
我试图将输入数据加载到错误的分区,但收到错误:
$ echo "1,3.14,2018-11-07" > row.csv
$ bq load "tmp_elliottb.PartitionedTable\$20181105" ./row.csv
Some rows belong to different partitions rather than destination partition 20181105
然后,我替换了分区的数据:
$ echo "1,3.14,2018-11-07" > row.csv
$ bq load "tmp_elliottb.PartitionedTable\$20181107" ./row.csv
$ echo "2,0.11,2018-11-07" > row.csv
$ bq load --replace "tmp_elliottb.PartitionedTable\$20181107" ./row.csv
是的,您可以使用
MERGE
作为替换分区表分区数据的一种方式,但您也可以使用加载作业。谢谢!我回头看了一下为什么我认为这是不可能的,这是因为我从Airflow收到了一条错误消息(在本例中,它不能准确反映BigQuery API)。对于我的用例,此解决方案比DML好得多,因为它处理模式随时间增加而更新的情况(因此不一致),我似乎无法处理DML,因为它要求我明确列出要插入到表中的所有列。@conradlee那么,您是如何使用Airflow操作符用新数据更新BQ表的?我有一个场景,我的现有表被一个日期列分区,而我的增量加载会为该表带来数据在过去三天中,尝试加载数据失败,出现错误异常:BigQuery作业失败。最终错误为:{'reason':'invalid','message':'某些行属于不同的分区,而不是目标分区20191202'}
非常感谢您在这方面提供的帮助。您好,您能为几个分区添加将在分区表中执行删除和插入操作的DML吗?谢谢!我返回并查看了我认为这不可能的原因,这是因为我收到了来自Airflow的错误消息(在本例中,它不能准确地反映BigQueryAPI)。对于我的用例,该解决方案比DML好得多,因为它处理模式随着时间的推移而不断更新(因此不一致)的情况,我似乎无法处理DML,因为它要求我明确列出要插入到表中的所有列。@conradlee那么,您是如何使用Airflow操作符用新数据更新BQ表的?我有一个场景,我的现有表被一个日期列分区,而我的增量加载会为该表带来数据在过去三天中,尝试加载数据失败,出现错误异常:BigQuery作业失败。最终错误为:{'reason':'invalid','message':'某些行属于不同的分区,而不是目标分区20191202'}
非常感谢您在这方面提供的任何帮助。您是否可以为多个分区添加将在分区表中执行删除和插入操作的DML?