Sovrascrivere in modo selettivo i dati con Delta Lake

Delta Lake offre le seguenti opzioni distinte per sovrascritture selettive:

Opzione Caso di utilizzo Tipi di calcolo supportati Versione minima
REPLACE WHERE Sovrascrivere in modo atomico le righe che corrispondono a un predicato. Da usare per le sostituzioni con una condizione di corrispondenza fissa, ad esempio colA = 5 o int_col IN (1, 2, 3). Tutti i tipi di calcolo. SQL in Databricks Runtime 12.2 LTS e versioni successive. Python e Scala in Databricks Runtime 9.1 LTS e versioni successive.
REPLACE USING Sovrascrittura dei dati dinamici. Sostituisce tutte le righe che corrispondono alle colonne specificate, in base al confronto di uguaglianza dei valori di colonna, nel set di dati specificato. Tutti i tipi di calcolo. SQL in Databricks Runtime 16.3 e versioni successive. Python e Scala in Databricks Runtime 18.2 e versioni successive.
REPLACE ON Sovrascrittura dei dati dinamici tramite espressione booleana. Utilizzare per le sostituzioni con una condizione di corrispondenza complessa o che gestisce in modo sicuro i valori NULL, ad esempio s.colA <=> t.colA AND s.colB <=> t.colB. Tutti i tipi di calcolo. SQL in Databricks Runtime 17.1 e versioni successive. Python e Scala in Databricks Runtime 18.2 e versioni successive.
partitionOverwriteMode Sovrascrittura dinamica tradizionale delle partizioni, che sovrascrive tutti i dati esistenti in ciascuna partizione in cui la scrittura eseguirà il commit di nuovi dati. Non consigliato per i nuovi carichi di lavoro. SQL supporta solo il calcolo classico. Python e Scala supportano tutti i tipi di calcolo. SQL, Python e Scala in Databricks Runtime 11.3 LTS e versioni successive.

Per la maggior parte dei casi d'uso, Databricks consiglia di usare REPLACE USING o REPLACE WHERE. Utilizzare REPLACE ON solo se lo scenario d'uso richiede condizioni di corrispondenza complesse o sicure rispetto a NULL.

Per informazioni dettagliate sul comportamento di sostituzione di ogni opzione, vedere INSERT. Per un elenco completo delle opzioni di DataFrameWriter Delta Lake, vedere Delta Lake e Apache Iceberg.

In Scala e Python non è possibile usare replaceOn e replaceUsing in combinazione con replaceWhere, partitionOverwriteMode o overwriteSchema.

Con query di origine vuote, sia REPLACE USING che REPLACE ON non eliminano dati; tuttavia, REPLACE WHERE potrebbe eliminarli.

Important

Se i dati sono stati accidentalmente sovrascritti, è possibile usare il ripristino per annullare la modifica.

REPLACE WHERE

È possibile sovrascrivere in modo selettivo solo i dati che corrispondono a un'espressione arbitraria con REPLACE WHERE.

Important

Per trarre vantaggio dall'aggiornamento incrementale quando si esegue REPLACE WHERE, utilizzare i flussi REPLACE WHERE nelle pipeline dichiarative di Spark (SDP). Vedi Elaborazione batch con flussi REPLACE WHERE.

Per sostituire in modo atomico gli eventi nel mese di gennaio nella tabella di destinazione, partizionata per start_date, con i dati in 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

Questo codice di esempio scrive i dati in replace_data, convalida che tutte le righe corrispondano al predicato ed esegue una sostituzione atomica usando overwrite la semantica. Se i valori nell'operazione non rientrano nel predicato, l'operazione ha esito negativo con un errore per impostazione predefinita.

Nel compute classico, per modificare questo comportamento in modo da ottenere overwrite valori all'interno dell'intervallo del predicato e insert record all'esterno dell'intervallo specificato, disattiva il controllo del vincolo impostando spark.databricks.delta.replaceWhere.constraintCheck.enabled su 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 accetta un oggetto boolean_expression con alcune restrizioni. Consultare INSERT nel riferimento linguistico SQL.

In caso di query di origine vuote, REPLACE WHERE potrebbe eliminare righe della tabella.

Comportamento legacy

La versione legacy replaceWhere è disponibile solo nel calcolo classico. Vedere Panoramica del calcolo classico.

Se si usa il comportamento legacy di replaceWhere, le query sovrascrivono i dati che corrispondono a un predicato solo sulle colonne di partizione. Il comando seguente sostituisce in modo atomico il mese di gennaio nella tabella di destinazione, partizionato da date, con i dati in 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")

Per usare il comportamento precedente, impostare spark.databricks.delta.replaceWhere.dataColumns.enabled su 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

Sovrascritture di dati dinamici

I dati dinamici sovrascrivono in modo selettivo i dati che corrispondono alle colonne chiave specificate o all'espressione booleana, lasciando invariati tutti gli altri dati. Sono supportate tutte le tabelle partizionate, le tabelle non partizionate e le tabelle con clustering liquido.

Le sovrascrizioni delle partizioni dinamiche sono un subset di comportamenti di sovrascrittura dei dati dinamici. Le sovrascritture dinamiche delle partizioni sostituiscono tutti i dati esistenti in ogni partizione in cui verranno scritti nuovi dati e lasciano invariate tutte le altre partizioni. Sono supportate solo le tabelle partizionate.

REPLACE USING

SQL supportato in Databricks Runtime 16.3 e versioni successive. Python e Scala supportati in Databricks Runtime 18.2 e versioni successive. Per informazioni sulle differenze di comportamento in Databricks Runtime dalla versione 16.3 alla 17.1, consulta Comportamento precedente.

REPLACE USING abilita il comportamento di sovrascrittura atomica indipendente dal calcolo che funziona su Databricks SQL Warehouse, calcolo serverless e classico. REPLACE USING non richiede l'impostazione di una configurazione di sessione Spark.

REPLACE USING sostituisce le righe quando i valori delle colonne specificate risultano uguali secondo il criterio di uguaglianza. Tutti gli altri dati rimangono invariati.

Usare la sovrascrittura dei dati dinamici con 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

Per le query di origine vuote, REPLACE USING non elimina alcuna riga di tabella.

Per condizioni di corrispondenza complesse o con valori NULL, utilizzare invece REPLACE ON. Vedete REPLACE ON.

Consultare INSERT nel riferimento linguistico SQL.

Comportamento precedente

In Databricks Runtime da 16.3 a 17.1 REPLACE USING usa il comportamento legacy e consente solo sovrascrizioni delle partizioni dinamiche, mentre Databricks Runtime 17.2 e versioni successive consente la sovrascrittura dei dati dinamici.

Tenere presenti i vincoli e i comportamenti seguenti per REPLACE USING il comportamento legacy:

  • È necessario specificare il set completo delle colonne di partizione della tabella nella USING clausola .
  • Verificare sempre che i dati scritti tocchino solo le partizioni previste. Una singola riga nella partizione errata può sovrascrivere involontariamente l'intera partizione.

REPLACE ON

SQL supportato in Databricks Runtime 17.1 e versioni successive. Python e Scala supportati in Databricks Runtime 18.2 e versioni successive.

REPLACE ON sostituisce le righe quando soddisfano una condizione definita dall'utente, a differenza di REPLACE USING, che sostituisce le righe quando le colonne specificate risultano uguali in base all'operatore di uguaglianza. Usare REPLACE ON quando è necessaria la logica corrispondente che REPLACE USING non supporta, ad esempio la gestione dei NULL valori come uguali.

Facoltativamente, usare l'opzione targetAlias per specificare un alias per la tabella di destinazione e le .as() API o .alias() per specificare un alias per i dati di origine.

Per la sintassi SQL, vedere 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

Per le query di origine vuote, REPLACE ON non elimina alcuna riga di tabella.

Sovrascrittura della partizione dinamica con partitionOverwriteMode (legacy)

Important

Questa funzionalità è in Anteprima Pubblica.

Databricks Runtime 11.3 LTS e versioni successive supportano le sovrascrizioni delle partizioni dinamiche per le tabelle partizionate usando la modalità di sovrascrittura: INSERT OVERWRITE in SQL o una scrittura del DataFrame con df.write.mode("overwrite"). Questo tipo di sovrascrittura è disponibile solo per il calcolo classico, non per databricks SQL warehouse o per il calcolo serverless.

Avviso

Quando possibile, utilizzare INSERT REPLACE USING anziché "partition overwrite" su INSERT OVERWRITE PARTITION e spark.sql.sources.partitionOverwriteMode=dynamic. La sovrascrittura della partizione può utilizzare dati obsoleti quando si verificano cambiamenti nel partizionamento.

Per usare la modalità di sovrascrittura della partizione dinamica, impostare la configurazione spark.sql.sources.partitionOverwriteMode della sessione Spark su dynamic. In alternativa, è possibile impostare l'opzione DataFrameWriterpartitionOverwriteMode su dynamic. Se presente, l'opzione specifica della query sostituisce la modalità definita nella configurazione della sessione. Il valore predefinito per spark.sql.sources.partitionOverwriteMode è static.

Nell'esempio seguente viene usato 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")

Tenere presenti i vincoli e i comportamenti seguenti per partitionOverwriteMode:

  • Non è possibile impostare overwriteSchema su true.
  • Non è possibile specificare sia partitionOverwriteMode che replaceWhere nella stessa operazione DataFrameWriter.
  • Se si specifica una replaceWhere condizione usando un'opzione DataFrameWriter , Delta Lake applica tale condizione per controllare quali dati vengono sovrascritti. Questa opzione ha la precedenza sulla partitionOverwriteMode configurazione a livello di sessione.
  • Verificare sempre che i dati scritti tocchino solo le partizioni previste. Una singola riga nella partizione errata può sovrascrivere involontariamente l'intera partizione.