Delta Lake-táblaséma frissítése

A Delta Lake lehetővé teszi egy tábla sémájának frissítését. A következő típusú módosítások támogatottak:

  • Új oszlopok hozzáadása (tetszőleges pozícióban)
  • Meglévő oszlopok átrendezése
  • Meglévő oszlopok átnevezése

Ezeket a módosításokat explicit módon DDL használatával vagy implicit módon DML használatával is elvégezheti.

Fontos

A Delta-táblaséma frissítése olyan művelet, amely ütközik az összes egyidejű Delta írási művelettel.

Amikor frissíti egy Delta-tábla sémáját, megszűnnek az adott táblát olvasó streamek. Ha azt szeretné, hogy a stream folytatódjon, újra kell indítania. Az ajánlott módszerekért tekintse meg a strukturált streamelés éles környezettel kapcsolatos szempontjait.

Séma explicit frissítése oszlopok hozzáadásához

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

Alapértelmezés szerint a nullabilitás a következő true: .

Ha oszlopot szeretne hozzáadni egy beágyazott mezőhöz, használja a következőt:

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

Ha például a séma futtatása ALTER TABLE boxes ADD COLUMNS (colB.nested STRING AFTER field1) előtt a következő:

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

a séma a következő után következik:

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

Feljegyzés

Beágyazott oszlopok hozzáadása csak a szerkezetek esetében támogatott. A tömbök és a térképek nem támogatottak.

Explicit módon frissítse a sémát az oszlop megjegyzésének vagy sorrendjének módosításához

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

Beágyazott mező oszlopának módosításához használja a következőt:

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

Ha például a séma futtatása ALTER TABLE boxes ALTER COLUMN colB.field2 FIRST előtt a következő:

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

a séma a következő után következik:

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

Explicit módon frissítse a sémát az oszlopok cseréjéhez

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

Például a következő DDL futtatásakor:

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

ha az előző séma a következő:

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

a séma a következő után következik:

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

Séma explicit frissítése oszlopok átnevezéséhez

Fontos

Ez a funkció a nyilvános előzetes verzióban érhető el.

Feljegyzés

Ez a funkció a Databricks Runtime 10.4 LTS és újabb verziókban érhető el.

Az oszlopok átnevezéséhez az oszlopok meglévő adatainak újraírása nélkül engedélyeznie kell az oszlopleképezést a táblához. Lásd: Oszlopok átnevezése és elvetése Delta Lake-oszlopleképezéssel.

Oszlop átnevezése:

ALTER TABLE table_name RENAME COLUMN old_col_name TO new_col_name

Beágyazott mező átnevezése:

ALTER TABLE table_name RENAME COLUMN col_name.old_nested_field TO new_nested_field

Ha például a következő parancsot futtatja:

ALTER TABLE boxes RENAME COLUMN colB.field1 TO field001

Ha az előző séma a következő:

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

Ezután a séma a következő:

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

Lásd: Oszlopok átnevezése és elvetése Delta Lake-oszlopleképezéssel.

Explicit módon frissítse a sémát az oszlopok elvetésére

Fontos

Ez a funkció a nyilvános előzetes verzióban érhető el.

Feljegyzés

Ez a funkció a Databricks Runtime 11.3 LTS és újabb verziókban érhető el.

Ha csak metaadat-műveletként szeretné elvetni az oszlopokat adatfájlok újraírása nélkül, engedélyeznie kell a tábla oszlopleképezését. Lásd: Oszlopok átnevezése és elvetése Delta Lake-oszlopleképezéssel.

Fontos

Az oszlop metaadatokból való elvetése nem törli a fájlokban lévő oszlop alapjául szolgáló adatokat. Az elvetett oszlopadatok törléséhez a REORG TABLE használatával átírhatja a fájlokat. Ezután a VACUUM használatával fizikailag törölheti az elvetett oszlopadatokat tartalmazó fájlokat.

Oszlop elvetése:

ALTER TABLE table_name DROP COLUMN col_name

Több oszlop elvetése:

ALTER TABLE table_name DROP COLUMNS (col_name_1, col_name_2)

Explicit módon frissítse a sémát az oszloptípus vagy -név módosításához

Módosíthatja egy oszlop típusát vagy nevét, vagy elvethet egy oszlopot a tábla újraírásával. Ehhez használja a overwriteSchema lehetőséget.

Az alábbi példa egy oszloptípus módosítását mutatja be:

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

Az alábbi példa egy oszlopnév módosítását mutatja be:

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

Oszlopok hozzáadása automatikus sémafrissítéssel

A DataFrame-ben található, de a táblából hiányzó oszlopok automatikusan hozzáadódnak egy írási tranzakció részeként, amikor:

  • write vagy writeStream rendelkezik .option("mergeSchema", "true")
  • spark.databricks.delta.schema.autoMerge.enabled a true

Ha mindkét beállítás meg van adva, a beállítás elsőbbséget DataFrameWriter élvez. A hozzáadott oszlopok hozzá vannak fűzve a struktúra végéhez, amelyben megtalálhatók. A kis- és nagybetűk megmaradnak egy új oszlop hozzáfűzésekor.

Feljegyzés

  • mergeSchema nem használható a következővel INSERT INTO : vagy .write.insertInto().

A Delta Lake-egyesítés automatikus sémafejlődése

A sémafejlődés lehetővé teszi a felhasználók számára a sémaeltérések feloldását a cél és a forrástábla egyesítésével. A következő két esetet kezeli:

  1. A forrástábla egyik oszlopa nem szerepel a céltáblában. Az új oszlop hozzáadódik a célsémához, és az értékei a forrásértékek használatával lesznek beszúrva vagy frissítve.
  2. A céltábla egyik oszlopa nem szerepel a forrástáblában. A célséma változatlan marad; a további céloszlop értékei változatlanok maradnak (for UPDATE) vagy (for ) értékre NULLINSERTvannak állítva.

Fontos

A sémafejlődés használatához be kell állítania a Spark-munkamenet konfigurációját spark.databricks.delta.schema.autoMerge.enabledtrue a merge parancs futtatása előtt.

Feljegyzés

  • A Databricks Runtime 12.2 LTS-ben és újabb verziókban a forrástáblában található oszlopok név szerint adhatók meg a beszúrási vagy frissítési műveletekben. A Databricks Runtime 11.3 LTS-ben és alatta csak INSERT * vagy UPDATE SET * műveletek használhatók a sémafejlődéshez az egyesítéssel.

Íme néhány példa a sémafejlődéssel és anélkül végzett működés hatásaira merge .

Oszlopok Lekérdezés (SQL-ben) Viselkedés sémafejlődés nélkül (alapértelmezett) Viselkedés sémafejlődéssel
Céloszlopok: key, value

Forrásoszlopok: 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 *
A táblaséma változatlan marad; csak oszlopok key, value frissítve/beszúrva. A táblaséma a következőre (key, value, new_value)módosul: . A meglévő egyezésekkel rendelkező rekordok frissülnek a forrásban és new_value a value forrásban. A rendszer új sorokat szúr be a sémával (key, value, new_value).
Céloszlopok: key, old_value

Forrásoszlopok: 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 és INSERT a műveletek hibát jeleznek, mert a céloszlop old_value nem szerepel a forrásban. A táblaséma a következőre (key, old_value, new_value)módosul: . A meglévő egyezésekkel rendelkező rekordok frissülnek a new_value forrásban változatlanul hagyva old_value . A rendszer új rekordokat szúr be a megadott keyés new_valueNULL a old_value.
Céloszlopok: key, old_value

Forrásoszlopok: 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 hibát jelez, mert az oszlop new_value nem létezik a céltáblában. A táblaséma a következőre (key, old_value, new_value)módosul: . A meglévő egyezésekkel rendelkező rekordok frissülnek a new_value forrásban változatlanul hagyva old_value , és a nem egyező rekordok be lettek NULL adva a következőhöz new_value: . Lásd az 1. megjegyzést.
Céloszlopok: key, old_value

Forrásoszlopok: 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 hibát jelez, mert az oszlop new_value nem létezik a céltáblában. A táblaséma a következőre (key, old_value, new_value)módosul: . A rendszer új rekordokat szúr be a megadott keyés new_valueNULL a old_value. A meglévő rekordok NULL változatlanok maradnak new_valueold_value . Lásd az 1. megjegyzést.

(1) Ez a viselkedés a Databricks Runtime 12.2 LTS és újabb verziókban érhető el; Ebben a feltételben a Databricks Runtime 11.3 LTS és az alábbi hiba jelenik meg.

Oszlopok kizárása Delta Lake-egyesítéssel

A Databricks Runtime 12.2 LTS-ben és újabb EXCEPT verziókban az oszlopok explicit kizárásához használhat záradékokat az egyesítési feltételekben. A kulcsszó viselkedése EXCEPT attól függően változik, hogy engedélyezve van-e a sémafejlődés.

Ha a sémafejlődés le van tiltva, a EXCEPT kulcsszó a céltáblában lévő oszlopok listájára vonatkozik, és lehetővé teszi az oszlopok kizárását a műveletekből vagy INSERT műveletekbőlUPDATE. A kizárt oszlopok értéke .null

Ha a sémafejlődés engedélyezve van, a EXCEPT kulcsszó a forrástáblában lévő oszlopok listájára vonatkozik, és lehetővé teszi az oszlopok kizárását a sémafejlődésből. A forrás olyan új oszlopa, amely nem szerepel a célban, nem lesz hozzáadva a célsémához, ha szerepel a EXCEPT záradékban. A célban már meglévő kizárt oszlopok a következőre nullvannak állítva: .

Az alábbi példák ezt a szintaxist mutatják be:

Oszlopok Lekérdezés (SQL-ben) Viselkedés sémafejlődés nélkül (alapértelmezett) Viselkedés sémafejlődéssel
Céloszlopok: id, title, last_updated

Forrásoszlopok: 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)
A egyeztetett sorok úgy frissülnek, hogy a last_updated mezőt az aktuális dátumra állítja. Az új sorok beszúrása a következő értékekkel id történik: és title. A kizárt mező last_updated értéke : null. A mező review figyelmen kívül lesz hagyva, mert nem szerepel a célban. A egyeztetett sorok úgy frissülnek, hogy a last_updated mezőt az aktuális dátumra állítja. A séma a mező reviewhozzáadásához fejlődik. Az új sorokat a program az összes forrásmezővel beszúrja, kivéve last_updated a következőt null: .
Céloszlopok: id, title, last_updated

Forrásoszlopok: 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 hibát jelez, mert az oszlop internal_count nem létezik a céltáblában. A egyeztetett sorok úgy frissülnek, hogy a last_updated mezőt az aktuális dátumra állítja. A review mező hozzáadódik a céltáblához, de a internal_count mező figyelmen kívül lesz hagyva. A beszúrt új sorok a következőre nullvannak last_updated állítva: .

Strukturált tömbök automatikus sémafejlődése

A Delta MERGE INTO támogatja a strukturált mezők név szerinti feloldását és a szerkezettömbök változó sémáinak feloldását. Ha engedélyezve van a sémafejlődés, a céltáblák sémái a strukturált tömbök esetében fejlődnek, ami a tömbökben lévő beágyazott szerkezetekkel is működik.

Feljegyzés

A Databricks Runtime 12.2 LTS-ben és újabb verziókban a forrástáblában található strukturált mezők név szerint megadhatóak a beszúrási vagy frissítési parancsokban. A Databricks Runtime 11.3 LTS-ben és alatta csak INSERT * vagy UPDATE SET * parancsok használhatók a sémafejlődéshez az egyesítéssel.

Íme néhány példa a szerkezettömbök sémafejlődésével és anélkül végzett egyesítési műveletek hatásaira.

Forrásséma Célséma Viselkedés sémafejlődés nélkül (alapértelmezett) Viselkedés sémafejlődéssel
tömbstruktúra<<b: sztring, a: sztring>> tömbstruktúra<<a: int, b: int>> A táblaséma változatlan marad. Az oszlopok a név alapján lesznek feloldva, és frissülnek vagy beszúrhatók. A táblaséma változatlan marad. Az oszlopok a név alapján lesznek feloldva, és frissülnek vagy beszúrhatók.
array<struct<a: int, c: string, d: string>> tömbstruktúra<<a: sztring, b: sztring>> update és insert hibajelzést ad, mert cd nem szerepel a céltáblában. A táblaséma tömbszerkezetre<változik<: sztring, b: sztring, c: sztring, d: sztring>>. c és d a céltábla meglévő bejegyzéseihez hasonlóan NULL lesz beszúrva. updateés insert töltse ki a forrástáblában lévő bejegyzéseket a sztringre és b a következőre NULLöntött elemekkela:
array<struct<a: string, b: struct<c: string, d: string>>> array<struct<a: string, b: struct<c: string>>> update és insert hibajelzést ad, mert d nem szerepel a céltáblában. A céltábla sémája tömbszerkezetre<<változik: sztring, b: struct<c: sztring, d: sztring>>>. d a céltábla meglévő bejegyzéseihez hasonlóan NULL lesz beszúrva.

A sémafrissítések oszlopainak NullType kezelése

Mivel a Parquet nem támogatja NullTypeaz oszlopokat, NullType a Rendszer elveti az oszlopokat a DataFrame-ből a Delta-táblákba való íráskor, de továbbra is a sémában tárolja őket. Ha egy másik adattípus érkezik az oszlophoz, a Delta Lake egyesíti a sémát az új adattípussal. Ha a Delta Lake kap egy NullType meglévő oszlopot, a régi séma megmarad, és az új oszlop el lesz dobva az írás során.

NullType a streamelés nem támogatott. Mivel a streamelés használatakor sémákat kell beállítania, ez nagyon ritka lehet. NullTypenem fogadható el olyan összetett típusok esetében is, mint például ArrayType a .MapType

Táblaséma cseréje

Alapértelmezés szerint a tábla adatainak felülírása nem írja felül a sémát. Ha felülír egy táblázatot mode("overwrite") anélkül replaceWhere, akkor is felülírhatja az éppen megírt adatok sémáját. A táblázat sémáját és particionálását a következő beállítással overwriteSchematruecserélheti le:

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

Fontos

A dinamikus partíció felülírása esetén nem adható meg overwriteSchematrue .