复制活动中的架构和数据类型映射

适用于: Azure 数据工厂 Azure Synapse Analytics

本文介绍如何Azure 数据工厂复制活动执行从源数据到接收器数据的架构映射和数据类型映射。

架构映射

默认映射

默认情况下,复制活动通过 列名 以区分大小写的方式将源数据映射到汇入。 如果 sink 不存在,例如在写入文件时,源字段名称将作为 sink 名称。 如果接收器已存在,则必须包含从源复制的所有列。 这种默认映射支持灵活的架构,以及在每次执行中从源到接收器的架构漂移——源数据存储返回的所有数据都可以复制到接收器。

如果你的源是没有头部的文本文件,你需要使用 显式映射 ,因为源不包含列名。

显式映射

指定显式映射以自定义从源到汇的列和字段映射。 通过显式映射,你可以仅将部分源数据复制到汇,将源数据映射到名称不同的汇,或重构表格数据或分层数据。 文案活动:

  1. 从源头读取数据并确定源模式。
  2. 应用已定义的映射。
  3. 将数据写入接收端。

了解有关以下方面的详细信息:

在创作界面中配置映射,方法是进入复制活动并选择 映射 标签。或者,通过使用该 translator 属性在复制活动中程序化地指定映射。 以下属性在 -translator> 数组 -mappings 对象 ->> 和 source中得到支持sink,这些属性指向特定的列或字段以映射数据。

房产 描述 必需
名字 源列或接收器列或字段的名称。 适用于表格源和汇。
ordinal 列索引。 从1开始。 当使用不带表头行的分隔符文本时,此项适用且为必需项。
路径 要提取或映射的每个字段的 JSON 路径表达式。 适用于分层源和汇,例如Azure Cosmos DB、Azure DocumentDB(兼容MongoDB)、MongoDB或REST连接器。 对于根对象下的字段,JSON 路径以根 $ 开头;对于 collectionReference 属性选择的数组内的字段,JSON 路径从没有 $ 的数组元素开始。
类型 源或接收器列的临时数据类型。 通常无需指定或更改此属性。 欲了解更多信息,请参见 数据类型映射
区域性 源或接收器列的区域性。 当类型为 DatetimeDatetimeoffset时适用。 默认值为 en-us。 通常无需指定或更改此属性。 欲了解更多信息,请参见 数据类型映射
格式 当类型为 DatetimeDatetimeoffset 时使用的格式字符串。 请参阅自定义日期和时间格式字符串,了解如何设置日期时间格式。 通常无需指定或更改此属性。 欲了解更多信息,请参见 数据类型映射

translator 外,mappings 下还支持以下属性:

房产 描述 必需
collectionReference 适用于从分层源复制数据,如 Azure Cosmos DB、Azure DocumentDB(兼容 MongoDB)、MongoDB 或 REST 连接器。 若要进行迭代操作,以同一模式从数组字段中的对象提取数据并按行和对象进行转换,请指定要进行交叉应用的该数组的 JSON 路径。

表格源到表格接收器

例如,将数据从 Salesforce 复制到Azure SQL 数据库并显式映射三列:

  1. 在复制活动中,选择 映射 标签,然后选择 导入模式 以导入源模式和汇式模式。

  2. 映射所需字段,排除或删除其余字段。

表格到表格的映射

在复制活动负载中配置相同的映射(请参见 translator)。

{
    "name": "CopyActivityTabularToTabular",
    "type": "Copy",
    "typeProperties": {
        "source": { "type": "SalesforceSource" },
        "sink": { "type": "SqlSink" },
        "translator": {
            "type": "TabularTranslator",
            "mappings": [
                {
                    "source": { "name": "Id" },
                    "sink": { "name": "CustomerID" }
                },
                {
                    "source": { "name": "Name" },
                    "sink": { "name": "LastName" }
                },
                {
                    "source": { "name": "LastModifiedDate" },
                    "sink": { "name": "ModifiedDate" }
                }
            ]
        }
    },
    ...
}

要从不含标头行的分隔文本文件中复制数据,请使用列序号而不是列名来表示各列。

{
    "name": "CopyActivityTabularToTabular",
    "type": "Copy",
    "typeProperties": {
        "source": { "type": "DelimitedTextSource" },
        "sink": { "type": "SqlSink" },
        "translator": {
            "type": "TabularTranslator",
            "mappings": [
                {
                    "source": { "ordinal": "1" },
                    "sink": { "name": "CustomerID" }
                }, 
                {
                    "source": { "ordinal": "2" },
                    "sink": { "name": "LastName" }
                }, 
                {
                    "source": { "ordinal": "3" },
                    "sink": { "name": "ModifiedDate" }
                }
            ]
        }
    },
    ...
}

分层源到表格接收器

当你将数据从层次结构源复制到表格接收器时,复制活动支持以下功能:

  • 从对象和数组中提取数据。
  • 从数组中交叉应用具有相同模式的多个对象,在这种情况下,可以将一个 JSON 对象转换为表格结果中的多个记录。

如需更高级的层级到表格转换,请使用数据流

例如,如果你有源 Azure DocumentDB 或 MongoDB 文档,内容如下:

{
    "id": {
        "$oid": "592e07800000000000000000"
    },
    "number": "01",
    "date": "20170122",
    "orders": [
        {
            "prod": "p1",
            "price": 23
        },
        {
            "prod": "p2",
            "price": 13
        },
        {
            "prod": "p3",
            "price": 231
        }
    ],
    "city": [ { "name": "Seattle" } ]
}

要将数据复制到文本文件,请使用以下格式并带有头部行。 将数组(order_pd 和 order_price)中的数据展平,并与共同的根级信息(编号、日期和城市)进行交叉连接:

订单号 订单日期 order_pd 订单价格 city
01 20170122 P1 23 西雅图
01 20170122 P2 13 西雅图
01 20170122 P3 231 西雅图

在数据工厂创作界面中定义此映射:

  1. 在复制活动中,进入 映射 标签页,选择 导入 模式以导入源模式和汇入模式。 当服务在导入模式时采样顶部几个对象,如果没有字段出现,就将其添加到层级结构中的正确层——将鼠标悬停在现有字段名称上,选择添加节点、对象或数组。

  2. 选择要从中遍历和提取数据的数组。 界面会自动填入集合引用。 注意,该操作只支持单个数组。

  3. 将所需字段映射到接收器。 服务自动确定分层端对应的 JSON 路径。

注意

对于标记为集合引用的数组为空且你选择复选框的记录,整个记录会被跳过。

使用 UI 从分层映射到表格

你也可以切换到 高级编辑器。 你可以直接查看并编辑字段的 JSON 路径。 如果选择在此视图中添加新映射,请指定 JSON 路径。

使用高级编辑器从分层映射到表格

你可以在复制活动负载中配置相同的映射(请参见 translator):

{
    "name": "CopyActivityHierarchicalToTabular",
    "type": "Copy",
    "typeProperties": {
        "source": { "type": "MongoDbV2Source" },
        "sink": { "type": "DelimitedTextSink" },
        "translator": {
            "type": "TabularTranslator",
            "mappings": [
                {
                    "source": { "path": "$['number']" },
                    "sink": { "name": "orderNumber" }
                },
                {
                    "source": { "path": "$['date']" },
                    "sink": { "name": "orderDate" }
                },
                {
                    "source": { "path": "['prod']" },
                    "sink": { "name": "order_pd" }
                },
                {
                    "source": { "path": "['price']" },
                    "sink": { "name": "order_price" }
                },
                {
                    "source": { "path": "$['city'][0]['name']" },
                    "sink": { "name": "city" }
                }
            ],
            "collectionReference": "$['orders']"
        }
    },
    ...
}

表格/分层源到分层接收器

用户体验流类似于分层源到表格接收器

当将数据从表格源复制到层次结构接收器时,该服务不支持写入对象中的数组。

当将数据从分层源复制到分层目标时,可以通过选择对象或数组并将其映射到目标,而无需处理内部字段,从而保留整个层级的结构。

对于更高级的数据重塑变换,可以使用 数据流

参数化映射

要创建一个动态复制大量对象的模板化流水线,首先确定是否可以使用 默认映射 ,还是需要为每个对象定义 显式映射

如果你需要显式映射,请按照以下步骤操作:

  1. 定义一个带有流水线层级对象类型的参数,例如 mapping

  2. 参数化映射:在复制活动中,进入映射标签页,选择添加动态内容,然后选择你创建的参数。 活动载荷如下:

    {
        "name": "CopyActivityHierarchicalToTabular",
        "type": "Copy",
        "typeProperties": {
            "source": {...},
            "sink": {...},
            "translator": {
                "value": "@pipeline().parameters.mapping",
                "type": "Expression"
            },
            ...
        }
    }
    
  3. 构造要传递给映射参数的值。 它应该是 translator 定义的整个对象。 关于样本,请参见 显式映射 部分。 例如,对于表格源到表格接收器的复制,值应该是 {"type":"TabularTranslator","mappings":[{"source":{"name":"Id"},"sink":{"name":"CustomerID"}},{"source":{"name":"Name"},"sink":{"name":"LastName"}},{"source":{"name":"LastModifiedDate"},"sink":{"name":"ModifiedDate"}}]}

数据类型映射

复制活动通过以下流程将源类型映射到汇类型:

  1. 将源数据的本机数据类型转换为 Azure 数据工厂 和 Synapse 管道所使用的中间数据类型。
  2. 根据需要自动转换临时数据类型以匹配相应的汇类型。 此步骤适用于 默认映射显式映射
  3. 从临时数据类型转换为接收器原生数据类型。

复制活动目前支持以下中间数据类型:布尔、字节、字节数组、Datetime、DatetimeOffset、Decimal、Double、GUID、Int16、Int32、Int64、SByte、Single、String、Timespan、UInt16、UInt32和UInt64。

从源到接收器支持在临时类型之间进行以下数据类型转换。

源\接收器 布尔 字节数组 日期/时间 小数 浮点数 GUID 整数 字符串 TimeSpan
布尔
字节数组
日期/时间
小数
浮点数
GUID
整数
字符串
TimeSpan

(1) 日期/时间包括日期时间、日期时间偏移、日期和时间。

(2) 浮点数包括 Single 和 Double。

(3) 整数包括 SByte、Byte、Int16、UInt16、Int32、UInt32、Int64 和 UInt64。

注意

  • 目前,在表格数据之间复制时支持此类数据类型转换。 不支持分层源和汇,这意味着在源和汇的中间类型之间不存在系统定义的数据类型转换。
  • 此功能适用于最新的数据集模型。 如果在 UI 中未看到此选项,请尝试创建一个新数据集。

复制活动支持以下用于数据类型转换的属性(在程序化创作的 translator 部分下):

房产 描述 必需
typeConversion 实现新的数据类型转换体验。 考虑到后向兼容性,默认值为 false。 自2020年6月底以来,通过Data Factory创作UI创建的新复制活动,默认启用了这种数据类型转换,以获得最佳体验。 你可以在适用场景下的复制活动 -> 映射选项卡中看到以下类型转换设置。 若要以编程方式创建管道,需要将 typeConversion 属性显式设置为 true 以启用它。 对于在此功能发布之前创建的现有复制活动,你不会在创作 UI 上看到有关后向兼容的类型转换选项。
typeConversionSettings 一组类型转换设置。 当 typeConversion 设置为 true 时应用。 以下属性都属于此组。
typeConversionSettings
allowDataTruncation 复制期间使用不同类型将源数据转换为接收器数据(例如,从小数转换为整数,从 DatetimeOffset 转换为 Datetime)时,允许数据截断。
默认值为 true。
treatBooleanAsNumber 将布尔值视为数字,例如,将 true 视为 1。
默认值为 false。
dateFormat 在日期和字符串之间转换时设置字符串格式,例如 yyyy-MM-dd。 请参阅自定义日期和时间格式字符串,了解详细信息。
dateTimeFormat 在日期之间转换时格式化字符串,而不带时区偏移量和字符串,例如 yyyy-MM-dd HH:mm:ss.fff。 请参阅自定义日期和时间格式字符串,了解详细信息。
dateTimeOffsetFormat 在具有时区偏移量和字符串的日期之间转换时设置字符串的格式,例如 yyyy-MM-dd HH:mm:ss.fff zzz。 请参阅自定义日期和时间格式字符串,了解详细信息。
timeSpanFormat 在时间段和字符串之间转换时设置字符串格式,例如 dd\.hh\:mm。 请参阅自定义 TimeSpan 格式字符串,了解详细信息。
timeFormat 在时间与字符串之间转换时设置字符串格式,例如 HH:mm:ss.fff。 请参阅自定义日期和时间格式字符串,了解详细信息。
区域性 转换类型时使用的区域性信息,例如 en-usfr-fr

Example:

{
    "name": "CopyActivity",
    "type": "Copy",
    "typeProperties": {
        "source": {
        	"type": "ParquetSource"
        },
        "sink": {
            "type": "SqlSink"
        },
        "translator": {
            "type": "TabularTranslator",
            "typeConversion": true,
            "typeConversionSettings": {
                "allowDataTruncation": true,
                "treatBooleanAsNumber": true,
                "dateTimeFormat": "yyyy-MM-dd HH:mm:ss.fff",
                "dateTimeOffsetFormat": "yyyy-MM-dd HH:mm:ss.fff zzz",
                "timeSpanFormat": "dd\.hh\:mm",
                "culture": "en-gb"
            }
        }
	},
    ...
}

旧模型

注意

为了向后兼容,该服务仍支持以下模型,用于将源列或字段映射到接收器。 使用 模式映射中描述的新模型。 现在创作界面生成新模型。

备用列映射(旧模型)

要在表格形式的数据之间进行映射,请指定 copy activity -> translator -> columnMappings。 在这种情况下,输入和输出数据集都需要 structure 部分。 列映射支持 将源数据集结构中的全部或部分列映射到汇数据集结构中的所有列。 以下错误条件会导致异常:

  • 源数据存储查询结果没有你在输入数据集结构部分指定的列名。
  • 如果Sink数据存储(如果是预定义的模式)没有你在输出数据集结构部分指定的列名。
  • 目标数据集结构中的列数少于或多于映射中指定的列数。
  • 重复的映射。

在以下示例中,输入数据集有一个结构,并且它指向本地 Oracle 数据库中的表。

{
    "name": "OracleDataset",
    "properties": {
        "structure":
         [
            { "name": "UserId"},
            { "name": "Name"},
            { "name": "Group"}
         ],
        "type": "OracleTable",
        "linkedServiceName": {
            "referenceName": "OracleLinkedService",
            "type": "LinkedServiceReference"
        },
        "typeProperties": {
            "tableName": "SourceTable"
        }
    }
}

在本示例中,输出数据集包含一个结构,并指向 Salesfoce 中的表。

{
    "name": "SalesforceDataset",
    "properties": {
        "structure":
        [
            { "name": "MyUserId"},
            { "name": "MyName" },
            { "name": "MyGroup"}
        ],
        "type": "SalesforceObject",
        "linkedServiceName": {
            "referenceName": "SalesforceLinkedService",
            "type": "LinkedServiceReference"
        },
        "typeProperties": {
            "tableName": "SinkTable"
        }
    }
}

以下 JSON 定义管道中的复制活动。 源中的列通过 translator ->columnMappings 属性映射到接收器中的列。

{
    "name": "CopyActivity",
    "type": "Copy",
    "inputs": [
        {
            "referenceName": "OracleDataset",
            "type": "DatasetReference"
        }
    ],
    "outputs": [
        {
            "referenceName": "SalesforceDataset",
            "type": "DatasetReference"
        }
    ],
    "typeProperties":    {
        "source": { "type": "OracleSource" },
        "sink": { "type": "SalesforceSink" },
        "translator":
        {
            "type": "TabularTranslator",
            "columnMappings":
            {
                "UserId": "MyUserId",
                "Group": "MyGroup",
                "Name": "MyName"
            }
        }
    }
}

如果你用语法 "columnMappings": "UserId: MyUserId, Group: MyGroup, Name: MyName" 来指定列映射,仍然支持 as-is。

替代架构映射(遗留模型)

你可以指定复制活动 ->translator ->schemaMapping,以在层次结构数据和表格数据之间进行映射。 例如,你可以从MongoDB或REST复制到文本文件,也可以从Oracle复制到Azure Cosmos DB,用于MongoDB或Azure DocumentDB(兼容MongoDB)。 复制活动 translator 中的部分支持以下属性:

房产 描述 必需
类型 将复制活动翻译器的类型属性设置为: TabularTranslator
schemaMapping 一组键值对,表示 源端到汇端的映射关系。
- 键:代表源。 对于 表格来源,请指定数据集结构中定义的列名。 对于分层源,请为每个要提取并映射的字段指定 JSON 路径表达式。
- 值:代表汇聚。 对于 表格式汇,请指定数据集结构中定义的列名。 对于分层接收器,请为每个字段指定用于提取和映射的 JSON 路径表达式。
在使用分层数据时,对于根对象下的字段,JSON 路径以根 $ 开头;对于按 collectionReference 属性选择的数组中的字段,JSON 路径以数组元素开头。
collectionReference 若要进行迭代操作,以同一模式从数组字段中的对象提取数据并按行和对象进行转换,请指定要进行交叉应用的该数组的 JSON 路径。 仅当分层数据为源时,才支持此属性。

示例:从 MongoDB 复制到 Oracle:

例如,如果你有一个包含以下内容的MongoDB文档:

{
    "id": {
        "$oid": "592e07800000000000000000"
    },
    "number": "01",
    "date": "20170122",
    "orders": [
        {
            "prod": "p1",
            "price": 23
        },
        {
            "prod": "p2",
            "price": 13
        },
        {
            "prod": "p3",
            "price": 231
        }
    ],
    "city": [ { "name": "Seattle" } ]
}

你想通过展平数组内的数据(order_pd 和 order_price),并将其与共有的根级信息(编号、日期和城市)进行交叉连接,以以下格式将其复制到 Azure SQL 表中:

订单号 订单日期 order_pd 订单价格 city
01 20170122 P1 23 西雅图
01 20170122 P2 13 西雅图
01 20170122 P3 231 西雅图

将模式映射规则配置为以下复制活动 JSON 示例:

{
    "name": "CopyFromMongoDBToOracle",
    "type": "Copy",
    "typeProperties": {
        "source": {
            "type": "MongoDbV2Source"
        },
        "sink": {
            "type": "OracleSink"
        },
        "translator": {
            "type": "TabularTranslator",
            "schemaMapping": {
                "$.number": "orderNumber",
                "$.date": "orderDate",
                "prod": "order_pd",
                "price": "order_price",
                "$.city[0].name": "city"
            },
            "collectionReference":  "$.orders"
        }
    }
}

请参阅关于复制活动的其他文章: