Selektivní přepsání dat pomocí Delta Lake

Delta Lake má následující specifické možnosti pro selektivní přepisování:

Možnost Případ použití Podporované typy výpočetních prostředků Minimální verze
REPLACE WHERE Atomicky přepište řádky, které odpovídají predikátu. Slouží k nahrazení pevným shodným stavem, například colA = 5int_col IN (1, 2, 3). Všechny typy výpočetních prostředků. SQL v Databricks Runtime 12.2 LTS a novějších Python a Scala v Databricks Runtime 9.1 LTS a novějších.
REPLACE USING Přepsání dynamických dat Nahradí všechny řádky odpovídající zadaným sloupcům na základě porovnání rovnosti hodnot sloupců v zadané sadě dat. Všechny typy výpočetních prostředků. SQL v Databricks Runtime 16.3 a novějších. Python a Scala v Databricks Runtime 18.2 a novějších.
REPLACE ON Přepsání dynamických dat pomocí logického výrazu. Slouží k nahrazení složitým nebo bezpečným shodným stavem NULL, například s.colA <=> t.colA AND s.colB <=> t.colB. Všechny typy výpočetních prostředků. SQL v Databricks Runtime 17.1 a novějších. Python a Scala v Databricks Runtime 18.2 a novějších.
partitionOverwriteMode Původní dynamické přepsání oddílů, které přepíše všechna existující data v každém oddílu, do kterého zápis zapíše nová data. Nedoporučuje se pro nové úlohy. SQL podporuje pouze klasické výpočetní prostředky. Python a Scala podporují všechny typy výpočetních prostředků. SQL, Python a Scala v Databricks Runtime 11.3 LTS a novějších.

Pro většinu případů použití doporučuje Databricks používat REPLACE USING nebo REPLACE WHERE. REPLACE ON používejte pouze tehdy, pokud váš scénář použití vyžaduje složité nebo vůči hodnotě NULL bezpečné podmínky porovnávání.

Podrobnosti o chování při nahrazování u jednotlivých možností viz INSERT. Úplný seznam DataFrameWriter možností Delta Lake najdete v tématu Delta Lake a Apache Iceberg.

V jazyce Scala a Python nelze replaceOn a replaceUsing použít v kombinaci s replaceWhere, partitionOverwriteMode nebo overwriteSchema.

V případě prázdných zdrojových dotazů REPLACE USING ani REPLACE ON data neodstraňují, avšak REPLACE WHERE může data odstranit.

Important

Pokud byla data omylem přepsána, můžete změnu vrátit zpět pomocí obnovení.

REPLACE WHERE

Můžete selektivně přepsat pouze data, která odpovídají libovolnému výrazu .REPLACE WHERE

Important

Pokud chcete využít výhod přírůstkové aktualizace při spuštění REPLACE WHERE, použijte toky REPLACE WHERE v deklarativních kanálech Sparku (SDP). Viz Dávkové zpracování pomocí toků REPLACE WHERE.

Chcete-li atomicky nahradit události z ledna v cílové tabulce, která je particionovaná podle start_date, daty z 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

Tento ukázkový kód zapíše data do replace_data, ověří, že všechny řádky odpovídají predikátu a provádí atomické nahrazení pomocí overwrite sémantiky. Pokud některé hodnoty v operaci spadají mimo predikát, tato operace ve výchozím nastavení selže s chybou.

Pokud chcete u klasického výpočetního prostředí změnit toto chování na overwrite hodnoty v rozsahu predikátu a insert záznamů mimo zadanou oblast, odeberte kontrolu omezení nastavením spark.databricks.delta.replaceWhere.constraintCheck.enabled na 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 přijímá boolean_expression s určitými omezeními. Viz INSERT referenční informace k jazyku SQL.

V případě prázdných zdrojových dotazů může REPLACE WHERE odstranit řádky tabulky.

Zastaralé chování

Starší verze replaceWhere je dostupná jenom na klasických výpočetních prostředcích. Podívejte se na přehled klasických výpočetních prostředků.

Pokud použijete starší verzi chování replaceWhere, dotazy přepíší data, která odpovídají predikátu pouze přes sloupce oddílů. Následující příkaz by atomicky nahradil měsíc leden v cílové tabulce, která je rozdělená podle date, daty z 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")

Pokud chcete použít starší verzi chování, nastavte spark.databricks.delta.replaceWhere.dataColumns.enabled na false:

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

Dynamické přepisování dat

Selektivní přepsání dynamických dat nahradí data, která odpovídají zadaným klíčovým sloupcům nebo logickému výrazu, zatímco všechna ostatní data zůstávají beze změny. Jsou podporovány dělené tabulky, nedělené tabulky a tabulky s liquid clusteringem.

Dynamické přepisování oddílů je podmnožinou chování dynamického přepisování dat. Dynamické přepisy oddílů nahradí všechna stávající data v každém oddílu, do něhož se při zápisu uloží nová data, a všechny ostatní oddíly ponechají beze změny. Podporují se jenom dělené tabulky.

REPLACE USING

SQL je podporováno v Databricks Runtime 16.3 a novějších verzích. Python a Scala podporované v Databricks Runtime 18.2 a novějších. Rozdíly v chování mezi verzemi Databricks Runtime 16.3 až 17.1 najdete v tématu Dřívější chování.

REPLACE USING umožňuje chování nezávislé na výpočetních prostředcích, atomické přepsání, které funguje ve službě Databricks SQL Warehouse, bezserverovém výpočetním prostředí a klasickém výpočetním prostředí. REPLACE USING nevyžaduje, abyste nastavili konfiguraci relace Spark.

REPLACE USING nahradí řádky, pokud jsou si zadané sloupce rovny. Všechna ostatní data zůstávají beze změny.

Použití dynamického přepsání dat pomocí REPLACE USING:

Python

(sourceDataDF.write
  .mode("overwrite")
  .option("replaceUsing", "event_id, start_date")
  .saveAsTable("events")
)

Scala

sourceDataDF.write
  .mode("overwrite")
  .option("replaceUsing", "event_id, start_date")
  .saveAsTable("events")

SQL

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

V případě prázdných zdrojových dotazů REPLACE USING neodstraní žádné řádky tabulky.

Pro složité podmínky porovnání nebo podmínky porovnání bezpečné vůči hodnotě NULL použijte místo toho REPLACE ON. Viz REPLACE ON.

Viz INSERT referenční informace k jazyku SQL.

Původní chování

V Databricks Runtime 16.3 až 17.1 REPLACE USING používá starší chování a umožňuje pouze přepsat dynamické oddíly, zatímco Databricks Runtime 17.2 a vyšší umožňuje dynamické přepsání dat.

Mějte na paměti následující omezení a chování pro starší chování REPLACE USING:

  • V části USING musíte zadat úplnou sadu sloupců oddílů tabulky.
  • Vždy ověřte, že se data zapsaná zasáhnou pouze očekávané partitiony. Jeden řádek v nesprávném oddílu může neúmyslně přepsat celý oddíl.

REPLACE ON

SQL podporovaný ve službě Databricks Runtime 17.1 a novějších. Python a Scala podporované v Databricks Runtime 18.2 a novějších.

REPLACE ON nahrazuje řádky, pokud odpovídají podmínce definované uživatelem, na rozdíl od REPLACE USING, který nahrazuje řádky, když jsou zadané sloupce při porovnání podle rovnosti shodné. Použijte REPLACE ON , když potřebujete odpovídající logiku, která REPLACE USING nepodporuje, jako je například zacházení s NULL hodnotami jako se stejnými.

Volitelně lze pomocí možnosti targetAlias zadat alias pro cílovou tabulku a pomocí rozhraní API .as() nebo .alias() zadat alias pro zdrojová data.

Syntaxi SQL najdete v tématu INSERT.

Python

(sourceDataDF.alias("s")
  .write
  .mode("overwrite")
  .option("targetAlias", "t")
  .option("replaceOn", "s.event_id <=> t.event_id AND s.start_date <=> t.start_date")
  .saveAsTable("events")
)

Scala

sourceDataDF.as("s")
  .write
  .mode("overwrite")
  .option("targetAlias", "t")
  .option("replaceOn", "s.event_id <=> t.event_id AND s.start_date <=> t.start_date")
  .saveAsTable("events")

SQL

INSERT INTO TABLE events AS t
  REPLACE ON (s.event_id <=> t.event_id AND s.start_date <=> t.start_date)
  (SELECT * FROM source_data) AS s

V případě prázdných zdrojových dotazů REPLACE ON neodstraní žádné řádky tabulky.

Dynamické přepsání oddílů pomocí partitionOverwriteMode (starší)

Important

Tato funkce je ve verzi Public Preview.

Databricks Runtime 11.3 LTS a vyšší podporuje dynamické přepsání oddílů pro dělené tabulky pomocí režimu přepsání: buď INSERT OVERWRITE v SQL, nebo zápis datového rámce s df.write.mode("overwrite"). Tento typ přepsání je k dispozici pouze pro klasické výpočetní prostředky, nikoli pro datové sklady SQL Databricks nebo bezserverové výpočetní prostředky.

Výstraha

Pokud je to možné, použijte INSERT REPLACE USING místo přepsání oddílu pomocí INSERT OVERWRITE PARTITION a spark.sql.sources.partitionOverwriteMode=dynamic. Při změně dělení oddílů může při přepisování oddílu docházet k používání zastaralých dat.

Pokud chcete použít přepisování dynamických oddílů, nastavte konfiguraci spark.sql.sources.partitionOverwriteMode relace Sparku na dynamic. Alternativně můžete nastavit DataFrameWriter možnost partitionOverwriteModedynamic. Pokud existuje, možnost specifická pro dotaz přepíše režim definovaný v konfiguraci relace. Výchozí hodnota pro spark.sql.sources.partitionOverwriteMode je static.

Následující příklad používá 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")

Mějte na paměti následující omezení a chování pro partitionOverwriteMode:

  • Nemůžete nastavit overwriteSchema na true.
  • Nemůžete zadat partitionOverwriteMode a replaceWhere v jedné operaci DataFrameWriter.
  • Pokud zadáte podmínku replaceWhere pomocí možnosti DataFrameWriter, Delta Lake tuto podmínku použije ke kontrole, která data se přepíšou. Tato možnost má přednost před partitionOverwriteMode konfigurací na úrovni relací.
  • Vždy ověřte, že se data zapsaná zasáhnou pouze očekávané partitiony. Jeden řádek v nesprávném oddílu může neúmyslně přepsat celý oddíl.