ADF复制Azure MySQL到Azure SQL时GUID与文本混合列复制失败
Azure Data Factory 跨库复制时混合内容列类型转换报错解决
故障表现
使用Azure Data Factory执行Azure Database for MySQL到Azure SQL Database的数据同步任务时,复制活动在modified_user_id列持续报错。该列存储混合格式内容,既有标准GUID格式值,也有普通数字、文本值,样例数据如下:
| modified_user_id |
|---|
| 3cf7716c-a759-59c6-bc93-57307e0eaaf4 |
| bd0c24c2-ca72-11e9-99a9-005056a673da |
| 1 |
| Administrator |
| 1 |
已知约束:
- 源端MySQL中该列数据类型为
char(36),目标端SQL Database中该列数据类型为varchar(36) - 源、目标表结构不可调整,无修改权限
- 当列中所有值均为GUID格式时,复制任务可正常运行;只要存在任意一个非GUID格式值,任务立即失败
当前复制活动核心配置、源/目标数据集列配置如下:
// 复制活动配置 { "name": "Copy data1", "type": "Copy", "dependsOn": [ { "activity": "truncate accounts", "dependencyConditions": [ "Succeeded" ] } ], "policy": { "timeout": "7.00:00:00", "retry": 0, "retryIntervalInSeconds": 30, "secureOutput": false, "secureInput": false }, "userProperties": [], "typeProperties": { "source": { "type": "AzureMySqlSource", "queryTimeout": "02:00:00" }, "sink": { "type": "AzureSqlSink", "writeBehavior": "insert", "sqlWriterUseTableLock": false, "disableMetricsCollection": false }, "enableStaging": false, "translator": { "type": "TabularTranslator", "mappings": [ { "source": { "name": "modified_user_id" }, "sink": { "name": "modified_user_id", "type": "String" } } ] } }, "inputs": [ { "referenceName": "accounts", "type": "DatasetReference" } ], "outputs": [ { "referenceName": "accounts_staging", "type": "DatasetReference" } ] }
// 源数据集该列配置 { "name": "modified_user_id", "type": "char", "precision": 0, "scale": 0 }
// 目标数据集该列配置 { "name": "modified_user_id", "type": "varchar" }
根本原因
报错和目标端字段类型无关,问题出在源端读取阶段的自动类型推断逻辑:
Azure MySQL的官方驱动默认会对字符类型字段做格式扫描,默认扫描前若干行数据判断字段实际类型:如果扫描到的行全是符合GUID格式的36位字符串,驱动会直接将该列的运行时类型标记为Guid而非String,后续读取行数据时会强制按Guid类型做解析。
此时如果碰到非GUID格式的普通文本值(比如1、Administrator),解析逻辑会直接抛出类型转换错误,任务终止。
当前配置的列映射仅指定了sink端的类型为String,没有显式约束源端的读取类型,无法覆盖驱动的自动推断行为,因此即使两端都是文本类型,依然会报错。
修复方案
以下方案均无需修改源、目标表结构,按需选择即可:
- 显式指定源列映射类型
修改复制活动的字段映射配置,给源端的modified_user_id列也显式标记类型为String,强制ADF按字符串类型读取该列,跳过驱动的自动类型推断,修改后的映射段如下:"mappings": [ { "source": { "name": "modified_user_id", "type": "String" }, "sink": { "name": "modified_user_id", "type": "String" } } ] - 源查询强制类型转换
不要用默认的全表读取,在AzureMySqlSource配置中自定义查询语句,对该列做显式类型转换,从查询层面固定返回值为字符串类型,示例:SELECT CAST(modified_user_id AS CHAR(36)) AS modified_user_id -- 其余字段按实际表结构补全 FROM accounts - 链接服务层面关闭GUID自动识别
编辑Azure Database for MySQL的链接服务,在连接字符串末尾追加参数Guids=false,关闭驱动对char类型字段的GUID自动识别逻辑,所有char类字段都会按原始字符串读取。
内容的提问来源于stack exchange,提问作者Petr
相关产品推荐
相关产品推荐

