共用方式為


選擇性地使用 Delta Lake 覆寫數據

Delta Lake 擁有以下特別的選擇性覆寫功能:

  • 選項會以原子性方式取代所有符合指定述詞的記錄。
  • 您可以使用動態分割覆寫功能,根據資料表的分割方式來取代資料目錄。

針對大部分的作業,Databricks 建議使用 replaceWhere 來指定要覆寫的數據。

Important

如果數據遭到意外覆寫,您可以使用 還原 來復原變更。

使用任意選擇性覆寫 replaceWhere

您可以選擇性地只覆寫符合任意表達式的數據。

Note

SQL 需要 Databricks Runtime 12.2 LTS 或更新版本。

例如,將目標資料表中以start_date分割的分區內的一月份事件原子性地替換為replace_data中的資料。

Python

(replace_data.write
  .mode("overwrite")
  .option("replaceWhere", "start_date >= '2017-01-01' AND end_date <= '2017-01-31'")
  .saveAsTable("events")
)

Scala

replace_data.write
  .mode("overwrite")
  .option("replaceWhere", "start_date >= '2017-01-01' AND end_date <= '2017-01-31'")
  .saveAsTable("events")

SQL

INSERT INTO TABLE events REPLACE WHERE start_date >= '2017-01-01' AND end_date <= '2017-01-31' SELECT * FROM replace_data

此範例程式碼將寫出replace_data中的數據,並驗證所有資料列是否符合預期條件,使用overwrite語意進行原子性取代。 如果作業中的任何值落在條件約束之外,此作業預設會失敗並出現錯誤。

您可以將此行為變更為 overwrite 述詞範圍內的值,以及 insert 落在指定範圍外的記錄。 若要這樣做,請使用下列其中一個設定,將 設定 spark.databricks.delta.replaceWhere.constraintCheck.enabled 為 false 來停用條件約束檢查:

Python

spark.conf.set("spark.databricks.delta.replaceWhere.constraintCheck.enabled", False)

Scala

spark.conf.set("spark.databricks.delta.replaceWhere.constraintCheck.enabled", false)

SQL

SET spark.databricks.delta.replaceWhere.constraintCheck.enabled=false

Note

REPLACE WHERE 接受 a boolean_expression 但有一些限制。 請參閱 SQL 語言參考中的 INSERT

遺留行為

如果您使用舊版行為 replaceWhere,查詢只會匹配分區欄位上的謂詞,並忽略不在謂詞範圍內的資料。 以下指令將原子式地替換以date分區的目標資料表中的一月份,使用df中的資料:

Python

(df.write
  .mode("overwrite")
  .option("replaceWhere", "birthDate >= '2017-01-01' AND birthDate <= '2017-01-31'")
  .saveAsTable("people10m")
)

Scala

df.write
  .mode("overwrite")
  .option("replaceWhere", "birthDate >= '2017-01-01' AND birthDate <= '2017-01-31'")
  .saveAsTable("people10m")

要使用舊有行為,請將旗標設 spark.databricks.delta.replaceWhere.dataColumns.enabledfalse

Python

spark.conf.set("spark.databricks.delta.replaceWhere.dataColumns.enabled", False)

Scala

spark.conf.set("spark.databricks.delta.replaceWhere.dataColumns.enabled", false)

SQL

SET spark.databricks.delta.replaceWhere.dataColumns.enabled=false

動態分割區覆寫

動態分割區覆寫僅更新寫入新資料的分割區,其他分割區則保持不變。

Azure Databricks 建議使用 REPLACE USING 來觸發動態分割區覆寫。 此模式適用於所有運算類型,包括 Databricks SQL 倉庫、無伺服器運算和經典運算,且不需要設定 Spark 會話設定。 參見動態分割覆寫。REPLACE USING

partitionOverwriteMode 是一種用於動態分割區覆寫的舊有模式,需要使用經典運算並設定 Spark 會話設定。 Databricks SQL 或無伺服器運算不支援此功能。 請參見 使用 partitionOverwriteMode 覆寫動態分割區(legacy)

以下章節示範如何使用每種模式。

使用動態分割區進行覆寫 REPLACE USING

Databricks Runtime 16.3 及以上版本支持使用 REPLACE USING 的資料表進行動態分割區覆寫。 你可以選擇性地覆蓋所有運算類型的資料,無需設定 Spark 會話設定。 REPLACE USING 啟用計算無關的原子性覆寫行為,可作用於 Databricks SQL 倉儲、無伺服器計算和傳統計算上。

REPLACE USING 只會覆寫傳入數據的目標分割區。 所有其他分割區保持不變。

REPLACE USING 僅支援 SQL 版本。 如需詳細資訊,請參閱 INSERT SQL 語言參考。

以下範例將使用 REPLACE USING

INSERT INTO TABLE events
  REPLACE USING (event_id, start_date)
  SELECT * FROM source_data

針對動態分割區覆寫,請記住下列限制和行為:

  • 在 Databricks Runtime 17.2 及以上版本中,支援分割資料表、未分割資料表,以及具備液態叢集的資料表。
  • 在 Databricks 執行時 16.3 至 17.1 中,僅支援分割區資料表,且必須在條款 USING 中指定資料表的完整分割欄位集合。
  • 請一律驗證寫入的數據只會觸及預期的分割區。 在錯誤分割區中的單一列可能會意外地覆寫整個分區。

如果您需要比REPLACE USING支援更多的可自定義比對邏輯,例如將值視為NULL相等,請改用互補。REPLACE ON 如需詳細資訊,請參閱 INSERT

動態分割區以覆寫(partitionOverwriteMode 舊版)

Important

這項功能目前處於 公開預覽版

Databricks Runtime 11.3 LTS 及以上版本支援在 SQL 中使用 INSERT OVERWRITE 或在 DataFrame 使用 df.write.mode("overwrite") 的方式,針對分區表進行動態覆寫。 這種類型的覆寫僅適用於傳統計算,不適用於 Databricks SQL 倉儲或無伺服器計算。

警告

若可能,請使用 INSERT OVERWRITE REPLACE USING partition overwrite INSERT OVERWRITE PARTITIONspark.sql.sources.partitionOverwriteMode=dynamic代替。 分割區覆寫在分割變更時可能會使用過時的資料。

若要使用動態分割區覆寫模式,請將 Spark 會話設定 spark.sql.sources.partitionOverwriteModedynamic。 或,您可以將 選項DataFrameWriter設定partitionOverwriteModedynamic。 存在時,查詢特定的選項會覆蓋會話配置中定義的模式。 spark.sql.sources.partitionOverwriteMode 的預設值為 static

下列範例會使用 partitionOverwriteMode

SQL

SET spark.sql.sources.partitionOverwriteMode=dynamic;
INSERT OVERWRITE TABLE default.people10m SELECT * FROM morePeople;

Python

(df.write
  .mode("overwrite")
  .option("partitionOverwriteMode", "dynamic")
  .saveAsTable("default.people10m")
)

Scala

df.write
  .mode("overwrite")
  .option("partitionOverwriteMode", "dynamic")
  .saveAsTable("default.people10m")

請記住下列條件約束和行為模式 partitionOverwriteMode

  • 您無法將 設定 overwriteSchematrue
  • 您無法在相同的partitionOverwriteMode作業中同時指定 replaceWhereDataFrameWriter
  • 如果您使用replaceWhere選項指定DataFrameWriter條件,Delta Lake 會套用該條件來控制哪些數據被覆寫。 此選項的優先順序高於會話層級設定 partitionOverwriteMode
  • 請一律驗證寫入的數據只會觸及預期的分割區。 在錯誤分割區中的單一列可能會意外地覆寫整個分區。