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 true
null-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:
- Stel het
.option("mergeSchema", "true")
in op een Spark DataFramewrite
ofwriteStream
-bewerking. Zie Schemaontwikkeling inschakelen voor schrijfbewerkingen om nieuwe kolommen toe te voegen. - Gebruik
MERGE WITH SCHEMA EVOLUTION
de syntaxis. Zie de syntaxis voor de ontwikkeling van schema's voor samenvoegen. - Stel de Spark-conf
spark.databricks.delta.schema.autoMerge.enabled
intrue
op voor de huidige SparkSession.
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:
- 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.
- 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 opNULL
(voorINSERT
).
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_value en 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_value en 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 review toe 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.