架构实施

Azure Databricks 通过对 Delta Lake 表实施写入时架构强制检查来确保数据质量。 架构强制执行不适用于使用非 Delta 格式的表,例如云存储中的 CSV 或 JSON 文件。

针对 INSERT 操作的架构强制执行

Azure Databricks将数据插入表中时强制实施以下规则:

  • 所有插入的列都必须存在于目标表中。
  • 所有列数据类型必须与目标表中的列数据类型匹配。

注意

Azure Databricks尝试安全转换列数据类型以匹配目标表。

INSERT 示例

例如,插入包含目标表中不存在的列的行会失败:

-- Fails: unknown_column does not exist in target_table
INSERT INTO catalog.schema.target_table (id, unknown_column) VALUES (1, 'value');

使用兼容的类型强制转换进行插入会成功:

-- Succeeds: integer 42 is safely cast to BIGINT
INSERT INTO catalog.schema.target_table (id, bigint_column) VALUES (1, 42);

针对 MERGE 操作的架构强制执行

Azure Databricks在插入或更新数据作为 MERGE 操作的一部分时强制实施以下规则:

  • 如果源语句中的数据类型与目标列不匹配,MERGE 会尝试安全地强制转换列数据类型以匹配目标表。
  • UPDATEINSERT 操作的目标列必须存在于目标表中。
  • 使用 INSERT *UPDATE SET *
    • 源数据集必须包含目标表中存在的所有列。
    • 强制执行会忽略源数据集中目标表里不存在的列。

MERGE 示例

例如,以下 MERGE 操作失败,因为查询尝试将值插入其中 unknown_column,该值不存在于 target_table

MERGE INTO catalog.schema.target_table AS t
USING catalog.schema.source_table AS s
ON t.id = s.id
WHEN MATCHED THEN UPDATE SET t.unknown_column = s.value
WHEN NOT MATCHED THEN INSERT (id, unknown_column) VALUES (s.id, s.value);

在另一个示例中,假定target_table具有列idname并且source_table具有idname,以及extra_col。 下面的 MERGE 使用 INSERT *,忽略源中的 extra_col,并且能够成功,因为源中存在所有目标列:

MERGE INTO catalog.schema.target_table AS t
USING catalog.schema.source_table 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

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

Python

df.write.option("mergeSchema", "true").mode("append").saveAsTable("catalog.schema.table_name")

架构演变对于 INSERTMERGE 操作具有特殊的语义。 请参阅启用架构演变

外部表

如果您在 Azure Databricks 之外直接使用外部客户端修改外部表的元数据,或通过基于路径的访问方式进行修改,Unity Catalog 不会自动将这些更新同步到其架构中。 这可能会导致架构约束无法正确生效。

运行 MSCK REPAIR TABLE <table-name> SYNC METADATA 以将架构与 Unity 目录同步。 请参阅 REPAIR TABLE