スキーマ強制
Databricksは、Delta Lakeテーブルへの書き込み時にスキーマを強制することで、データ品質を検証します。スキーマ強制は、クラウドストレージ内のCSVやJSONファイルなど、非Delta形式を使用するテーブルには適用されません。
INSERT操作のスキーマ強制
Databricks では、テーブルにデータを挿入するときに次のルールが適用されます。
- 挿入されたすべての列は、ターゲット表に存在している必要があります。
- すべての列データ型は、ターゲット表の列データ型と一致する必要があります。
Databricks は、ターゲット テーブルに一致するように列のデータ型を安全にキャストしようとします。
INSERT の例
以下の例では、enforce_demo という名前の管理 Delta Lake テーブルに書き込みます。これを作成するには、以下を実行します:
CREATE OR REPLACE TABLE main.default.enforce_demo (id INT, name STRING, amount BIGINT);
enforce_demo に unknown_column が存在しないため、以下の INSERT は失敗します。Databricks は、有効な列名を提案する UNRESOLVED_COLUMN.WITH_SUGGESTION エラー (SQLSTATE 42703) を返します:
INSERT INTO main.default.enforce_demo (id, unknown_column) VALUES (1, 'value');
以下の INSERT は成功します。Databricks は、整数 42 を amount 列の BIGINT 型に安全にキャストします:
INSERT INTO main.default.enforce_demo (id, amount) VALUES (1, 42);
MERGE操作のスキーマ強制
Databricks では、 MERGE 操作の一部としてデータを挿入または更新するときに、次のルールが適用されます。
- ソース ステートメントのデータ・タイプがターゲット・カラムと一致しない場合、
MERGEはカラム・データ・タイプをターゲット・テーブルと一致するように安全にキャストしようとします。 UPDATEまたはINSERTアクションのターゲットカラムは、ターゲットテーブルに存在する必要があります。INSERT *またはUPDATE SET *を使用する場合:- ソース データセットには、ターゲット テーブルに存在するすべての列が含まれている必要があります。
- 適用により、ターゲットテーブルに存在しないソースデータセットの列は無視されます。
MERGE の例
次の例では、前のセクションの enforce_demo テーブルと、余分な列を持つ enforce_source という名前のソーステーブルを再利用します。ソーステーブルを作成するには、以下を実行します:
CREATE OR REPLACE TABLE main.default.enforce_source (id INT, name STRING, amount BIGINT, extra_col STRING);
INSERT INTO main.default.enforce_source VALUES (1, 'Alice', 100, 'x'), (2, 'Bob', 200, 'y');
enforce_demo に存在しない unknown_column に割り当てようとするため、以下の MERGE は失敗します。Databricks は、解決可能な列名を指定する DELTA_MERGE_UNRESOLVED_EXPRESSION エラーを返します:
MERGE INTO main.default.enforce_demo AS t
USING main.default.enforce_source AS s
ON t.id = s.id
WHEN MATCHED THEN UPDATE SET t.unknown_column = s.name
WHEN NOT MATCHED THEN INSERT (id, unknown_column) VALUES (s.id, s.name);
enforce_source テーブルには、enforce_demo にはない extra_col 列が含まれています。ソースにすべてのターゲットカラムが含まれているため、INSERT * を使用した次の MERGE は成功します。適用時に extra_col は無視されます:
MERGE INTO main.default.enforce_demo AS t
USING main.default.enforce_source AS s
ON t.id = s.id
WHEN NOT MATCHED THEN INSERT *;
テーブル スキーマの変更
明示的な ALTER TABLE ステートメントまたは自動スキーマ進化を使用して、テーブルのスキーマを更新できます。スキーマ進化を使用してテーブルスキーマを更新するを参照してください。
たとえば、列を明示的に追加するには:
ALTER TABLE catalog.schema.table_name ADD COLUMN new_column STRING;
書き込み操作で自動スキーマ進化を有効にするには、mergeSchema オプションを設定します。
- SQL
- Python
SET spark.databricks.delta.schema.autoMerge.enabled = true;
INSERT INTO catalog.schema.table_name SELECT * FROM source_table;
df.write.option("mergeSchema", "true").mode("append").saveAsTable("catalog.schema.table_name")
スキーマ進化には、 INSERTおよびMERGE操作に対する特別なセマンティクスがあります。「スキーマ進化を有効にする」を参照してください。
外部テーブル
Databricks の外部にある外部クライアントで、またはパスベースのアクセスを使用して、外部テーブルのメタデータを直接変更した場合、Unity Catalog はスキーマへの更新を自動的に同期しません。これにより、スキーマ強制が正しく適用されなくなる可能性があります。
MSCK REPAIR TABLE <table-name> SYNC METADATA を実行してスキーマを Unity Catalog に同期します。REPAIR TABLEを参照してください。