Aracılığıyla paylaş


Delta Lake tablo şemasını güncelleştirin

Delta Lake, bir tablonun şemasını güncelleştirmenizi sağlar. Aşağıdaki değişiklik türleri desteklenir:

  • Yeni sütunlar ekleme (rastgele konumlarda)
  • Mevcut sütunları yeniden sıralama
  • Varolan sütunları yeniden adlandırma

Bu değişiklikleri açıkça DDL kullanarak veya örtük olarak DML kullanarak yapabilirsiniz.

Önemli

Delta tablosu şemasına yönelik güncelleştirme, tüm eşzamanlı Delta yazma işlemleriyle çakişen bir işlemdir.

Delta tablosu şemasını güncelleştirdiğinizde, bu tablodan okunan akışlar sonlanır. Akışın devam etmesi için akışı yeniden başlatmanız gerekir. Önerilen yöntemler için bkz . Yapılandırılmış Akış için üretimde dikkat edilmesi gerekenler.

Sütun eklemek için şemayı açıkça güncelleştirin

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

Varsayılan olarak null atanabilirlik değeridir true.

İç içe bir alana sütun eklemek için şunu kullanın:

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

Örneğin, çalıştırmadan ALTER TABLE boxes ADD COLUMNS (colB.nested STRING AFTER field1) önceki şema aşağıdaki gibiyse:

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

sonrasındaki şema:

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

Not

İç içe sütunlar eklemek yalnızca yapılar için desteklenir. Diziler ve eşlemeler desteklenmez.

Sütun açıklamasını veya sıralamasını değiştirmek için şemayı açıkça güncelleştirin

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

İç içe bir alandaki sütunu değiştirmek için şunu kullanın:

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

Örneğin, çalıştırmadan ALTER TABLE boxes ALTER COLUMN colB.field2 FIRST önceki şema aşağıdaki gibiyse:

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

sonrasındaki şema:

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

Sütunları değiştirmek için şemayı açıkça güncelleştirin

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

Örneğin, aşağıdaki DDL'yi çalıştırırken:

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

önceki şema şuysa:

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

sonrasındaki şema:

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

Şemayı sütunları yeniden adlandırmak için açıkça güncelleştirin

Not

Bu özellik Databricks Runtime 10.4 LTS ve üzerinde kullanılabilir.

Sütunların var olan verilerini yeniden yazmadan sütunları yeniden adlandırmak için tablo için sütun eşlemeyi etkinleştirmeniz gerekir. Bkz . Delta Lake sütun eşlemesi ile sütunları yeniden adlandırma ve bırakma.

Sütunu yeniden adlandırmak için:

ALTER TABLE table_name RENAME COLUMN old_col_name TO new_col_name

İç içe bir alanı yeniden adlandırmak için:

ALTER TABLE table_name RENAME COLUMN col_name.old_nested_field TO new_nested_field

Örneğin, aşağıdaki komutu çalıştırdığınızda:

ALTER TABLE boxes RENAME COLUMN colB.field1 TO field001

Önceki şema şuysa:

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

Ardından aşağıdaki şema şu şekildedir:

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

Bkz . Delta Lake sütun eşlemesi ile sütunları yeniden adlandırma ve bırakma.

Şemayı sütunları bırakacak şekilde açıkça güncelleştirin

Not

Bu özellik Databricks Runtime 11.3 LTS ve üzerinde kullanılabilir.

Herhangi bir veri dosyasını yeniden yazmadan sütunları yalnızca meta veri işlemi olarak bırakmak için, tablo için sütun eşlemeyi etkinleştirmeniz gerekir. Bkz . Delta Lake sütun eşlemesi ile sütunları yeniden adlandırma ve bırakma.

Önemli

Bir sütunu meta verilerden kaldırmak, dosyalardaki sütunun temel verilerini silmez. Bırakılan sütun verilerini temizlemek için REORG TABLE kullanarak dosyaları yeniden yazabilirsiniz. Ardından, bırakılan sütun verilerini içeren dosyaları fiziksel olarak silmek için VACUUM kullanabilirsiniz.

Bir sütunu bırakmak için:

ALTER TABLE table_name DROP COLUMN col_name

Birden çok sütunu bırakmak için:

ALTER TABLE table_name DROP COLUMNS (col_name_1, col_name_2)

Sütun türünü veya adını değiştirmek için şemayı açıkça güncelleştirin

Bir sütunun türünü veya adını değiştirebilir veya tabloyu yeniden yazarak bir sütunu bırakabilirsiniz. Bunu yapmak için seçeneğini kullanın overwriteSchema .

Aşağıdaki örnekte sütun türünü değiştirme gösterilmektedir:

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

Aşağıdaki örnekte sütun adını değiştirme gösterilmektedir:

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

Şema evrimi etkinleştir

Aşağıdakilerden birini yaparak şema evrimini etkinleştirebilirsiniz:

  • öğesini .option("mergeSchema", "true") bir Spark DataFrame write veya writeStream işlemi olarak ayarlayın. Bkz . Yeni sütunlar eklemek için yazma işlemleri için şema evrimi etkinleştirme.
  • Söz dizimlerini kullanın MERGE WITH SCHEMA EVOLUTION . Birleştirme için bkz. Şema evrimi söz dizimi.
  • Geçerli SparkSession için Spark konfunu spark.databricks.delta.schema.autoMerge.enabled true olarak ayarlayın.

Databricks, Spark konfederasyonu ayarlamak yerine her yazma işlemi için şema evrimini etkinleştirmenizi önerir.

Bir yazma işleminde şema evrimini etkinleştirmek için seçenekleri veya söz dizimini kullandığınızda, bu Spark konfederasyonundan önceliklidir.

Not

Deyimler için INSERT INTO şema evrimi yan tümcesi yoktur.

Yeni sütunlar eklemek için yazma işlemleri için şema evrimi etkinleştirme

Şema evrimi etkinleştirildiğinde, kaynak sorguda mevcut olan ancak hedef tabloda eksik olan sütunlar otomatik olarak yazma işleminin bir parçası olarak eklenir. Bkz . Şema evrimi etkinleştirme.

Yeni sütun eklenirken büyük/küçük harf korunur. Tablo şemasının sonuna yeni sütunlar eklenir. Ek sütunlar bir yapıdaysa, bunlar hedef tablodaki yapının sonuna eklenir.

Aşağıdaki örnekte, Seçeneğin mergeSchema Otomatik Yükleyici ile birlikte kullanılması gösterilmektedir. Bkz. Otomatik Yükleyici nedir?.

(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")
)

Aşağıdaki örnekte, seçeneğinin mergeSchema toplu yazma işlemiyle kullanılması gösterilmektedir:

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

Delta Lake birleştirme için otomatik şema evrimi

Şema evrimi, kullanıcıların birleştirmedeki hedef ve kaynak tablo arasındaki şema uyuşmazlıklarını çözmesine olanak tanır. Aşağıdaki iki durumu işler:

  1. Kaynak tablodaki bir sütun hedef tabloda yok. Yeni sütun hedef şemaya eklenir ve değerleri kaynak değerler kullanılarak eklenir veya güncelleştirilir.
  2. Hedef tablodaki bir sütun kaynak tabloda yok. Hedef şema değişmeden bırakılır; ek hedef sütundaki değerler değişmeden bırakılır (içinUPDATE) veya (içinINSERT) olarak NULL ayarlanır.

Otomatik şema geliştirmeyi el ile etkinleştirmeniz gerekir. Bkz . Şema evrimi etkinleştirme.

Not

Databricks Runtime 12.2 LTS ve üzerinde, kaynak tabloda bulunan sütunlar ve yapı alanları ekleme veya güncelleştirme eylemlerinde ada göre belirtilebilir. Databricks Runtime 11.3 LTS ve altında, birleştirme ile şema evrimi için yalnızca INSERT * veya UPDATE SET * eylemler kullanılabilir.

Databricks Runtime 13.3 LTS ve üzerinde, şema evrimi'ni gibi map<int, struct<a: int, b: int>>haritaların içine yerleştirilmiş yapılarla kullanabilirsiniz.

Birleştirme için şema evrimi söz dizimi

Databricks Runtime 15.2 ve üzerinde SQL veya Delta tablo API'lerini kullanarak birleştirme deyiminde şema evrimi belirtebilirsiniz:

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()

Şema evrimi ile birleştirme işlemi örneği

Şema evrimi ile ve şemasız işlemin etkilerinin merge birkaç örneği aşağıda verilmiştir.

Sütunlar Sorgu (SQL'de) Şema evrimi olmadan davranış (varsayılan) Şema evrimi ile davranış
Hedef sütunlar: key, value

Kaynak sütunlar: 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 *
Tablo şeması değişmeden kalır; yalnızca sütunları keyvalue güncelleştirilir/eklenir. Tablo şeması olarak (key, value, new_value)değiştirilir. Eşleşmeleri olan mevcut kayıtlar, kaynaktaki ve new_value ile value güncelleştirilir. Yeni satırlar şemasıyla (key, value, new_value)eklenir.
Hedef sütunlar: key, old_value

Kaynak sütunlar: 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 ve INSERT eylemleri, hedef sütun old_value kaynakta olmadığından bir hata oluşturur. Tablo şeması olarak (key, old_value, new_value)değiştirilir. Eşleşmeleri olan mevcut kayıtlar, kaynaktaki ile new_value değiştirilmemiş olarak old_value güncelleştirilir. Yeni kayıtlar, için old_valuebelirtilen key, new_valueve NULL ile eklenir.
Hedef sütunlar: key, old_value

Kaynak sütunlar: 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 hedef tabloda sütun new_value olmadığından hata oluşturur. Tablo şeması olarak (key, old_value, new_value)değiştirilir. Eşleşmeleri olan mevcut kayıtlar, kaynağında ile değiştirilmemiş olarak old_value güncelleştirilir new_value ve için new_valueeşleşmeyen kayıtlar NULL girilir. Nota bakın (1).
Hedef sütunlar: key, old_value

Kaynak sütunlar: 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 hedef tabloda sütun new_value olmadığından hata oluşturur. Tablo şeması olarak (key, old_value, new_value)değiştirilir. Yeni kayıtlar, için old_valuebelirtilen key, new_valueve NULL ile eklenir. Var olan kayıtlar NULL değişmeden ayrılmak old_value için new_value girildi. Nota bakın (1).

(1) Bu davranış Databricks Runtime 12.2 LTS ve üzerinde kullanılabilir; Databricks Runtime 11.3 LTS ve bu koşulda aşağıdaki hata.

Delta Lake birleştirme ile sütunları dışlama

Databricks Runtime 12.2 LTS ve üzerinde sütunları açıkça dışlamak için birleştirme koşullarında yan tümceleri kullanabilirsiniz EXCEPT . Anahtar sözcüğün davranışı, şema evriminin EXCEPT etkinleştirilip etkinleştirilmediğine bağlı olarak değişir.

Şema evrimi devre dışı bırakılarakEXCEPT, anahtar sözcük hedef tablodaki sütunların listesine uygulanır ve sütunların veya INSERT eylemlerin UPDATE dışlanmasını sağlar. Dışlanan sütunlar olarak nullayarlanır.

Şema evrimi EXCEPT etkinleştirildiğinde, anahtar sözcüğü kaynak tablodaki sütun listesine uygulanır ve sütunların şema evriminden dışlanmasını sağlar. Kaynakta hedefte bulunmayan yeni bir sütun, yan tümcesinde listeleniyorsa hedef şemaya EXCEPT eklenmez. Hedefte zaten var olan dışlanan sütunlar olarak nullayarlanır.

Aşağıdaki örneklerde bu söz dizimi gösterilmektedir:

Sütunlar Sorgu (SQL'de) Şema evrimi olmadan davranış (varsayılan) Şema evrimi ile davranış
Hedef sütunlar: id, title, last_updated

Kaynak sütunlar: 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)
Eşleşen satırlar, alanı geçerli tarihe last_updated ayarlanarak güncelleştirilir. Yeni satırlar ve titledeğerleri id kullanılarak eklenir. Dışlanan alan last_updated olarak nullayarlanır. Alan review hedefte olmadığından yoksayılır. Eşleşen satırlar, alanı geçerli tarihe last_updated ayarlanarak güncelleştirilir. Şema, alanını revieweklemek için geliştirilir. Yeni satırlar, olarak ayarlanmış nullolan dışındaki last_updated tüm kaynak alanlar kullanılarak eklenir.
Hedef sütunlar: id, title, last_updated

Kaynak sütunlar: 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 hedef tabloda sütun internal_count olmadığından hata oluşturur. Eşleşen satırlar, alanı geçerli tarihe last_updated ayarlanarak güncelleştirilir. Alan review hedef tabloya eklenir, ancak internal_count alan yoksayılır. Eklenen yeni satırlar last_updated olarak ayarlanmıştır null.

Şema güncelleştirmelerindeki sütunlarla NullType ilgilenme

Parquet desteklemediğindenNullTypeNullType, Delta tablolarına yazarken dataframe'den sütunlar bırakılır, ancak yine de şemada depolanır. Bu sütun için farklı bir veri türü alındığında Delta Lake şemayı yeni veri türüyle birleştirir. Delta Lake mevcut bir sütun için bir NullType alırsa, eski şema korunur ve yazma sırasında yeni sütun bırakılır.

NullType akışta desteklenmez. Akış kullanırken şemaları ayarlamanız gerektiğinden bu çok nadir olmalıdır. NullType ve gibi ArrayType MapTypekarmaşık türler için de kabul edilmez.

Tablo şemasını değiştirme

Varsayılan olarak, bir tablodaki verilerin üzerine yazmak şemanın üzerine yazılmaz. olmadan replaceWherekullanarak mode("overwrite") bir tablonun üzerine yazılırken, yine de yazılan verilerin şemasının üzerine yazmak isteyebilirsiniz. seçeneğini trueolarak ayarlayarak tablonun şemasını ve bölümlemini overwriteSchema değiştirirsiniz:

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

Önemli

Dinamik bölüm üzerine yazma kullanılırken olarak true belirtemezsinizoverwriteSchema.