Delen via


Delta Lake-tabelschema bijwerken

Met Delta Lake kunt u het schema van een tabel bijwerken. De volgende typen wijzigingen worden ondersteund:

  • Nieuwe kolommen toevoegen (op willekeurige posities)
  • Bestaande kolommen opnieuw ordenen
  • De naam van bestaande kolommen wijzigen

U kunt deze wijzigingen expliciet aanbrengen met DDL of impliciet met DML.

Belangrijk

Een update van een Delta-tabelschema is een bewerking die conflicteert met alle gelijktijdige Delta-schrijfbewerkingen.

Wanneer u een Delta-tabelschema bijwerkt, worden streams die uit die tabel worden gelezen, beƫindigd. Als u wilt dat de stream wordt voortgezet, moet u deze opnieuw starten. Zie Productieoverwegingen voor Gestructureerd streamen voor aanbevolen methoden.

Schema expliciet bijwerken om kolommen toe te voegen

ALTER TABLE table_name ADD COLUMNS (col_name data_type [COMMENT col_comment] [FIRST|AFTER colA_name], ...)

Standaard is truenull-waarde .

Als u een kolom wilt toevoegen aan een genest veld, gebruikt u:

ALTER TABLE table_name ADD COLUMNS (col_name.nested_col_name data_type [COMMENT col_comment] [FIRST|AFTER colA_name], ...)

Als het schema bijvoorbeeld wordt uitgevoerd voordat het wordt uitgevoerd ALTER TABLE boxes ADD COLUMNS (colB.nested STRING AFTER field1) :

- root
| - colA
| - colB
| +-field1
| +-field2

het schema erna is:

- root
| - colA
| - colB
| +-field1
| +-nested
| +-field2

Notitie

Het toevoegen van geneste kolommen wordt alleen ondersteund voor structs. Matrices en kaarten worden niet ondersteund.

Schema expliciet bijwerken om kolomcommentaar of -volgorde te wijzigen

ALTER TABLE table_name ALTER [COLUMN] col_name (COMMENT col_comment | FIRST | AFTER colA_name)

Als u een kolom in een genest veld wilt wijzigen, gebruikt u:

ALTER TABLE table_name ALTER [COLUMN] col_name.nested_col_name (COMMENT col_comment | FIRST | AFTER colA_name)

Als het schema bijvoorbeeld wordt uitgevoerd voordat het wordt uitgevoerd ALTER TABLE boxes ALTER COLUMN colB.field2 FIRST :

- root
| - colA
| - colB
| +-field1
| +-field2

het schema erna is:

- root
| - colA
| - colB
| +-field2
| +-field1

Schema expliciet bijwerken om kolommen te vervangen

ALTER TABLE table_name REPLACE COLUMNS (col_name1 col_type1 [COMMENT col_comment1], ...)

Bijvoorbeeld bij het uitvoeren van de volgende DDL:

ALTER TABLE boxes REPLACE COLUMNS (colC STRING, colB STRUCT<field2:STRING, nested:STRING, field1:STRING>, colA STRING)

als het schema eerder het volgende is:

- root
| - colA
| - colB
| +-field1
| +-field2

het schema erna is:

- root
| - colC
| - colB
| +-field2
| +-nested
| +-field1
| - colA

Schema expliciet bijwerken om de naam van kolommen te wijzigen

Notitie

Deze functie is beschikbaar in Databricks Runtime 10.4 LTS en hoger.

Als u de naam van kolommen wilt wijzigen zonder de bestaande gegevens van de kolommen te herschrijven, moet u kolomtoewijzing voor de tabel inschakelen. Zie De naam van kolommen wijzigen en neerzetten met delta lake-kolomtoewijzing.

De naam van een kolom wijzigen:

ALTER TABLE table_name RENAME COLUMN old_col_name TO new_col_name

De naam van een geneste veld wijzigen:

ALTER TABLE table_name RENAME COLUMN col_name.old_nested_field TO new_nested_field

Wanneer u bijvoorbeeld de volgende opdracht uitvoert:

ALTER TABLE boxes RENAME COLUMN colB.field1 TO field001

Als het schema eerder het volgende is:

- root
| - colA
| - colB
| +-field1
| +-field2

Vervolgens is het schema hierna:

- root
| - colA
| - colB
| +-field001
| +-field2

Zie De naam van kolommen wijzigen en neerzetten met delta lake-kolomtoewijzing.

Schema expliciet bijwerken om kolommen te verwijderen

Notitie

Deze functie is beschikbaar in Databricks Runtime 11.3 LTS en hoger.

Als u kolommen wilt verwijderen als een bewerking met alleen metagegevens zonder gegevensbestanden te herschrijven, moet u kolomtoewijzing voor de tabel inschakelen. Zie De naam van kolommen wijzigen en neerzetten met delta lake-kolomtoewijzing.

Belangrijk

Als u een kolom verwijdert uit metagegevens, worden de onderliggende gegevens voor de kolom in bestanden niet verwijderd. Als u de verwijderde kolomgegevens wilt opschonen, kunt u REORG TABLE gebruiken om bestanden te herschrijven. Vervolgens kunt u VACUUM gebruiken om de bestanden die de verwijderde kolomgegevens bevatten, fysiek te verwijderen.

Een kolom verwijderen:

ALTER TABLE table_name DROP COLUMN col_name

Meerdere kolommen verwijderen:

ALTER TABLE table_name DROP COLUMNS (col_name_1, col_name_2)

Schema expliciet bijwerken om het kolomtype of de naam te wijzigen

U kunt het type of de naam van een kolom wijzigen of een kolom verwijderen door de tabel opnieuw te schrijven. Gebruik hiervoor de overwriteSchema optie.

In het volgende voorbeeld ziet u hoe u een kolomtype wijzigt:

(spark.read.table(...)
  .withColumn("birthDate", col("birthDate").cast("date"))
  .write
  .mode("overwrite")
  .option("overwriteSchema", "true")
  .saveAsTable(...)
)

In het volgende voorbeeld ziet u hoe u een kolomnaam wijzigt:

(spark.read.table(...)
  .withColumnRenamed("dateOfBirth", "birthDate")
  .write
  .mode("overwrite")
  .option("overwriteSchema", "true")
  .saveAsTable(...)
)

Ontwikkeling van schema's inschakelen

U kunt schemaontwikkeling inschakelen door een van de volgende handelingen uit te voeren:

Databricks raadt aan om schemaontwikkeling in te schakelen voor elke schrijfbewerking in plaats van een Spark-conf in te stellen.

Wanneer u opties of syntaxis gebruikt om de ontwikkeling van schema's in een schrijfbewerking in te schakelen, heeft dit voorrang op de Spark-conf.

Notitie

Er is geen component voor schemaontwikkeling voor INSERT INTO instructies.

Schemaontwikkeling voor schrijfbewerkingen inschakelen om nieuwe kolommen toe te voegen

Kolommen die aanwezig zijn in de bronquery, maar ontbreken in de doeltabel, worden automatisch toegevoegd als onderdeel van een schrijftransactie wanneer schemaontwikkeling is ingeschakeld. Zie Ontwikkeling van schema inschakelen.

Hoofdletters blijven behouden bij het toevoegen van een nieuwe kolom. Nieuwe kolommen worden toegevoegd aan het einde van het tabelschema. Als de extra kolommen zich in een struct bevinden, worden ze toegevoegd aan het einde van de struct in de doeltabel.

In het volgende voorbeeld ziet u hoe u de optie gebruikt met automatisch mergeSchema laden. Zie Wat is automatisch laadprogramma?

(spark.readStream
  .format("cloudFiles")
  .option("cloudFiles.format", "json")
  .option("cloudFiles.schemaLocation", "<path-to-schema-location>")
  .load("<path-to-source-data>")
  .writeStream
  .option("mergeSchema", "true")
  .option("checkpointLocation", "<path-to-checkpoint>")
  .trigger(availableNow=True)
  .toTable("table_name")
)

In het volgende voorbeeld ziet u hoe u de mergeSchema optie gebruikt met een batchschrijfbewerking:

(spark.read
  .table(source_table)
  .write
  .option("mergeSchema", "true")
  .mode("append")
  .saveAsTable("table_name")
)

Automatische schemaontwikkeling voor Delta Lake-samenvoeging

Met schemaontwikkeling kunnen gebruikers schema-verschillen tussen de doel- en brontabel in samenvoeging oplossen. De volgende twee gevallen worden afgehandeld:

  1. Een kolom in de brontabel is niet aanwezig in de doeltabel. De nieuwe kolom wordt toegevoegd aan het doelschema en de waarden worden ingevoegd of bijgewerkt met behulp van de bronwaarden.
  2. Een kolom in de doeltabel is niet aanwezig in de brontabel. Het doelschema blijft ongewijzigd; de waarden in de extra doelkolom ongewijzigd blijven (voor UPDATE) of ingesteld op NULL (voor INSERT).

U moet automatische schemaontwikkeling handmatig inschakelen. Zie Ontwikkeling van schema inschakelen.

Notitie

In Databricks Runtime 12.2 LTS en hoger kunnen kolommen en structvelden die aanwezig zijn in de brontabel worden opgegeven op naam in invoeg- of bijwerkacties. In Databricks Runtime 11.3 LTS en lager kunnen alleen INSERT * acties worden UPDATE SET * gebruikt voor het ontwikkelen van schema's met samenvoegen.

In Databricks Runtime 13.3 LTS en hoger kunt u schemaontwikkeling gebruiken met structs die zijn genest in kaarten, zoals map<int, struct<a: int, b: int>>.

Syntaxis voor de ontwikkeling van schema's voor samenvoegen

In Databricks Runtime 15.2 en hoger kunt u schemaontwikkeling opgeven in een samenvoeginstructie met behulp van SQL- of Delta-tabel-API's:

SQL

MERGE WITH SCHEMA EVOLUTION INTO target
USING source
ON source.key = target.key
WHEN MATCHED THEN
  UPDATE SET *
WHEN NOT MATCHED THEN
  INSERT *
WHEN NOT MATCHED BY SOURCE THEN
  DELETE

Python

from delta.tables import *

(targetTable
  .merge(sourceDF, "source.key = target.key")
  .withSchemaEvolution()
  .whenMatchedUpdateAll()
  .whenNotMatchedInsertAll()
  .whenNotMatchedBySourceDelete()
  .execute()
)

Scala

import io.delta.tables._

targetTable
  .merge(sourceDF, "source.key = target.key")
  .withSchemaEvolution()
  .whenMatched()
  .updateAll()
  .whenNotMatched()
  .insertAll()
  .whenNotMatchedBySource()
  .delete()
  .execute()

Voorbeeldbewerkingen van samenvoegen met schemaontwikkeling

Hier volgen enkele voorbeelden van de effecten van merge de werking met en zonder schemaontwikkeling.

Kolommen Query (in SQL) Gedrag zonder schemaontwikkeling (standaard) Gedrag met schemaontwikkeling
Doelkolommen: key, value

Bronkolommen: key, value, new_value
MERGE INTO target_table t
USING source_table s
ON t.key = s.key
WHEN MATCHED
THEN UPDATE SET *
WHEN NOT MATCHED
THEN INSERT *
Het tabelschema blijft ongewijzigd. alleen kolommen key, value worden bijgewerkt/ingevoegd. Het tabelschema wordt gewijzigd in (key, value, new_value). Bestaande records met overeenkomsten worden bijgewerkt met de value en new_value in de bron. Nieuwe rijen worden ingevoegd met het schema (key, value, new_value).
Doelkolommen: key, old_value

Bronkolommen: key, new_value
MERGE INTO target_table t
USING source_table s
ON t.key = s.key
WHEN MATCHED
THEN UPDATE SET *
WHEN NOT MATCHED
THEN INSERT *
UPDATE en INSERT acties veroorzaken een fout omdat de doelkolom old_value zich niet in de bron bevindt. Het tabelschema wordt gewijzigd in (key, old_value, new_value). Bestaande records met overeenkomsten worden bijgewerkt met de new_value in de bron ongewijzigd blijven old_value . Nieuwe records worden ingevoegd met de opgegeven key, new_valueen NULL voor de old_value.
Doelkolommen: key, old_value

Bronkolommen: key, new_value
MERGE INTO target_table t
USING source_table s
ON t.key = s.key
WHEN MATCHED
THEN UPDATE SET new_value = s.new_value
UPDATE genereert een fout omdat de kolom new_value niet bestaat in de doeltabel. Het tabelschema wordt gewijzigd in (key, old_value, new_value). Bestaande records met overeenkomsten worden bijgewerkt met de in de new_value bron ongewijzigd en old_value niet-overeenkomende records zijn NULL ingevoerd voor new_value. Zie opmerking (1).
Doelkolommen: key, old_value

Bronkolommen: key, new_value
MERGE INTO target_table t
USING source_table s
ON t.key = s.key
WHEN NOT MATCHED
THEN INSERT (key, new_value) VALUES (s.key, s.new_value)
INSERT genereert een fout omdat de kolom new_value niet bestaat in de doeltabel. Het tabelschema wordt gewijzigd in (key, old_value, new_value). Nieuwe records worden ingevoegd met de opgegeven key, new_valueen NULL voor de old_value. Bestaande records zijn NULL ingevoerd om new_value ongewijzigd te blijven old_value . Zie opmerking (1).

(1) Dit gedrag is beschikbaar in Databricks Runtime 12.2 LTS en hoger; Databricks Runtime 11.3 LTS en de onderstaande fout in deze voorwaarde.

Kolommen uitsluiten met Delta Lake-samenvoeging

In Databricks Runtime 12.2 LTS en hoger kunt u componenten in samenvoegvoorwaarden gebruiken EXCEPT om kolommen expliciet uit te sluiten. Het gedrag van het EXCEPT trefwoord varieert, afhankelijk van of de evolutie van het schema al dan niet is ingeschakeld.

Als de ontwikkeling van het schema is uitgeschakeld, is het EXCEPT trefwoord van toepassing op de lijst met kolommen in de doeltabel en is het mogelijk kolommen uit UPDATE of INSERT acties uit te sluiten. Uitgesloten kolommen zijn ingesteld op null.

Als schemaontwikkeling is ingeschakeld, is het EXCEPT trefwoord van toepassing op de lijst met kolommen in de brontabel en is het mogelijk kolommen uit te sluiten van schemaontwikkeling. Een nieuwe kolom in de bron die niet aanwezig is in het doel, wordt niet toegevoegd aan het doelschema als deze wordt vermeld in de EXCEPT component. Uitgesloten kolommen die al aanwezig zijn in het doel, zijn ingesteld op null.

In de volgende voorbeelden ziet u deze syntaxis:

Kolommen Query (in SQL) Gedrag zonder schemaontwikkeling (standaard) Gedrag met schemaontwikkeling
Doelkolommen: id, title, last_updated

Bronkolommen: id, title, review, last_updated
MERGE INTO target t
USING source s
ON t.id = s.id
WHEN MATCHED
THEN UPDATE SET last_updated = current_date()
WHEN NOT MATCHED
THEN INSERT * EXCEPT (last_updated)
Overeenkomende rijen worden bijgewerkt door het last_updated veld in te stellen op de huidige datum. Nieuwe rijen worden ingevoegd met behulp van waarden voor id en title. Het uitgesloten veld last_updated is ingesteld op null. Het veld review wordt genegeerd omdat het niet in het doel staat. Overeenkomende rijen worden bijgewerkt door het last_updated veld in te stellen op de huidige datum. Het schema is ontwikkeld om het veld reviewtoe te voegen. Nieuwe rijen worden ingevoegd met behulp van alle bronvelden, behalve last_updated die is ingesteld op null.
Doelkolommen: id, title, last_updated

Bronkolommen: id, title, review, internal_count
MERGE INTO target t
USING source s
ON t.id = s.id
WHEN MATCHED
THEN UPDATE SET last_updated = current_date()
WHEN NOT MATCHED
THEN INSERT * EXCEPT (last_updated, internal_count)
INSERT genereert een fout omdat de kolom internal_count niet bestaat in de doeltabel. Overeenkomende rijen worden bijgewerkt door het last_updated veld in te stellen op de huidige datum. Het review veld wordt toegevoegd aan de doeltabel, maar het internal_count veld wordt genegeerd. Nieuwe rijen die zijn ingevoegd, zijn last_updated ingesteld op null.

Omgaan met NullType kolommen in schema-updates

Omdat Parquet geen ondersteuning biedt NullType, NullType worden kolommen uit het DataFrame verwijderd bij het schrijven naar Delta-tabellen, maar worden ze nog steeds opgeslagen in het schema. Wanneer een ander gegevenstype voor die kolom wordt ontvangen, voegt Delta Lake het schema samen met het nieuwe gegevenstype. Als Delta Lake een NullType voor een bestaande kolom ontvangt, blijft het oude schema behouden en wordt de nieuwe kolom verwijderd tijdens de schrijfbewerking.

NullType streaming wordt niet ondersteund. Omdat u schema's moet instellen bij het gebruik van streaming, moet dit zeer zeldzaam zijn. NullType wordt ook niet geaccepteerd voor complexe typen, zoals ArrayType en MapType.

Tabelschema vervangen

Het schema wordt standaard niet overschreven door de gegevens in een tabel te overschrijven. Wanneer u een tabel overschrijft zonder mode("overwrite") replaceWhere, wilt u mogelijk nog steeds het schema overschrijven van de gegevens die worden geschreven. U vervangt het schema en de partitionering van de tabel door de overwriteSchema optie in te stellen op true:

df.write.option("overwriteSchema", "true")

Belangrijk

U kunt niet opgeven overwriteSchema als true bij het gebruik van dynamische partitie overschrijven.