解决Databricks中COPY命令的数据类型冲突问题
解决COPY INTO加载CSV到Delta表时TINYINT类型不兼容问题
问题根源
CSV文件中IS_ACTIVE列的内容是字符串形式的数字(比如"0"、"1"),启用inferSchema='true'时,Spark会将其推断为ByteType,而目标Delta表的IS_ACTIVE定义为TINYINT(本质上与ByteType属于同一类型),报错的核心原因是COPY命令在合并Schema时,源数据的类型推断结果与目标表类型出现了判定冲突。
解决方案(仅使用COPY命令)
方案1:手动指定源数据Schema,关闭自动推断
直接在FORMAT_OPTIONS中指定源CSV的完整Schema,强制将IS_ACTIVE解析为TINYINT,避免自动推断带来的类型偏差:
COPY INTO metadata.md_config_master FROM 'abfss://{container}@{storage_account}.dfs.core.windows.net/table_folder/' WITH (CREDENTIAL (AZURE_SAS_TOKEN = '<sas_token_string>') ) FILEFORMAT = CSV FILES = ('MD_CONFIG_MASTER.csv') FORMAT_OPTIONS ( 'header' = 'true', 'schema' = 'CONFIG_ID INT, CLIENT_NAME STRING, TARGET_DATABASE STRING, TARGET_DATABASE_MODULE_NAME STRING, TARGET_DATABASE_DRIVER_CLASS_NAME STRING, TARGET_DATABASE_CNX_INFO STRING, EXECUTION_PLATFORM STRING, IS_ACTIVE TINYINT, INSERT_DTS TIMESTAMP' ) COPY_OPTIONS ('force' = 'true', 'mergeSchema'= 'true')
方案2:在FROM子句中显式转换列类型
通过子查询对源CSV的IS_ACTIVE列进行类型转换,确保源数据类型与目标表完全匹配:
COPY INTO metadata.md_config_master FROM ( SELECT CONFIG_ID, CLIENT_NAME, TARGET_DATABASE, TARGET_DATABASE_MODULE_NAME, TARGET_DATABASE_DRIVER_CLASS_NAME, TARGET_DATABASE_CNX_INFO, EXECUTION_PLATFORM, CAST(IS_ACTIVE AS TINYINT) AS IS_ACTIVE, INSERT_DTS FROM 'abfss://{container}@{storage_account}.dfs.core.windows.net/table_folder/MD_CONFIG_MASTER.csv' ) WITH (CREDENTIAL (AZURE_SAS_TOKEN = '<sas_token_string>') ) FILEFORMAT = CSV FORMAT_OPTIONS ('header' = 'true') COPY_OPTIONS ('force' = 'true', 'mergeSchema'= 'true')
说明
- 方案1适合CSV结构固定的场景,直接强制解析规则,避免自动推断的不确定性;
- 方案2更灵活,适用于需要对特定列做转换处理的场景,确保类型完全对齐。
内容的提问来源于stack exchange,提问作者shankar
相关产品推荐
相关产品推荐

