メインコンテンツまでスキップ

スキーマ強制

Databricksは、Delta Lakeテーブルへの書き込み時にスキーマを強制することで、データ品質を検証します。スキーマ強制は、クラウドストレージ内のCSVやJSONファイルなど、非Delta形式を使用するテーブルには適用されません。

INSERT操作のスキーマ強制

Databricks では、テーブルにデータを挿入するときに次のルールが適用されます。

  • 挿入されたすべての列は、ターゲット表に存在している必要があります。
  • すべての列データ型は、ターゲット表の列データ型と一致する必要があります。
注記

Databricks は、ターゲット テーブルに一致するように列のデータ型を安全にキャストしようとします。

INSERT の例

以下の例では、enforce_demo という名前の管理 Delta Lake テーブルに書き込みます。これを作成するには、以下を実行します:

SQL
CREATE OR REPLACE TABLE main.default.enforce_demo (id INT, name STRING, amount BIGINT);

enforce_demounknown_column が存在しないため、以下の INSERT は失敗します。Databricks は、有効な列名を提案する UNRESOLVED_COLUMN.WITH_SUGGESTION エラー (SQLSTATE 42703) を返します:

SQL
INSERT INTO main.default.enforce_demo (id, unknown_column) VALUES (1, 'value');

以下の INSERT は成功します。Databricks は、整数 42amount 列の BIGINT 型に安全にキャストします:

SQL
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 という名前のソーステーブルを再利用します。ソーステーブルを作成するには、以下を実行します:

SQL
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 エラーを返します:

SQL
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 は無視されます:

SQL
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 ステートメントまたは自動スキーマ進化を使用して、テーブルのスキーマを更新できます。スキーマ進化を使用してテーブルスキーマを更新するを参照してください。

たとえば、列を明示的に追加するには:

SQL
ALTER TABLE catalog.schema.table_name ADD COLUMN new_column STRING;

書き込み操作で自動スキーマ進化を有効にするには、mergeSchema オプションを設定します。

SQL
SET spark.databricks.delta.schema.autoMerge.enabled = true;
INSERT INTO catalog.schema.table_name SELECT * FROM source_table;

スキーマ進化には、 INSERTおよびMERGE操作に対する特別なセマンティクスがあります。「スキーマ進化を有効にする」を参照してください。

外部テーブル

Databricks の外部にある外部クライアントで、またはパスベースのアクセスを使用して、外部テーブルのメタデータを直接変更した場合、Unity Catalog はスキーマへの更新を自動的に同期しません。これにより、スキーマ強制が正しく適用されなくなる可能性があります。

MSCK REPAIR TABLE <table-name> SYNC METADATA を実行してスキーマを Unity Catalog に同期します。REPAIR TABLEを参照してください。