

# 创建自定义转换
<a name="transforms-custom"></a>

如果需要对数据执行更复杂的转换，或者希望将数据属性键添加到数据集，则可以为您的任务图添加 **Custom code (自定义代码)** 转换。自定义代码节点允许您输入执行转换的脚本。

使用自定义代码时，必须使用架构编辑器来指示通过自定义代码对输出所做的更改。编辑架构时，您可以执行以下操作：
+ 添加或删除数据属性键
+ 更改数据属性键的数据类型
+ 更改数据属性键的名称。
+ 重构嵌套属性键

您必须使用 *SelectFromCollection* 转换，从自定义转换节点的结果中选择单个 `DynamicFrame`，然后将输出发送到目标位置。

使用以下任务，将自定义转换节点添加到任务图。

## 将自定义代码转换节点添加到任务图
<a name="transforms-custom-addnode"></a>

**将自定义转换节点添加到任务图**

1. （可选）打开资源面板，然后选择**自定义转换**将自定义转换添加到作业图。

1. 在 **Node properties (节点属性)** 选项卡上，输入任务图中节点的名称。如果尚未选择父节点，或者您希望为自定义转换选择多个输入，请从 **Node parents (父节点)** 列表中选择一个节点，用作转换的输入源。

## 输入自定义转换节点的代码
<a name="transforms-custom-addcode"></a>

您可以将代码输入或复制到输入字段。任务使用此代码执行数据转换。您可以以 Python 或 Scala 提供代码片段。该代码应采用一个或多个 `DynamicFrames` 作为输入，并返回 `DynamicFrames`。

**输入自定义转换节点的脚本**

1. 在任务图中选择了自定义变换节点后，选择 **Transform (转换)** 选项卡。

1. 在标题 **Code block (代码数据块)** 下的文本输入字段中，粘贴或输入转换节点。您使用的代码必须与 **Job details (任务详细信息)** 选项卡上为任务指定的语言匹配。

   当引用代码中的输入节点时，AWS Glue Studio 会命名根据创建顺序返回的 `DynamicFrames` 任务图节点。在代码中使用以下命名方法之一：
   + 经典代码生成 – 使用功能名称引用任务图中的节点。
     + 数据源节点：`DataSource0`、`DataSource1`、`DataSource2` 等。
     + 转换节点：`Transform0`、`Transform1`、`Transform2` 等。
   + 新代码生成 – 使用节点的 **Node properties**（节点属性）选项卡上指定的名称，并附加“`_node1`”、“`_node2`”等。例如，`S3bucket_node1`、`ApplyMapping_node2`、`S3bucket_node2`、`MyCustomNodeName_node1`。

   有关新代码生成器的更多信息，请参阅 [脚本代码生成](job-editor-features.md#code-gen)。

以下示例显示了要在代码框中输入的代码的格式：

------
#### [ Python ]

下面的示例采用收到的第一个 `DynamicFrame`，将其转换为 `DataFrame` 以应用本地筛选方法（仅保留拥有超过 1000 票的记录），然后在返回前将其转换回 `DynamicFrame`。

```
def FilterHighVoteCounts (glueContext, dfc) -> DynamicFrameCollection:
    df = dfc.select(list(dfc.keys())[0]).toDF()
    df_filtered = df.filter(df["vote_count"] > 1000)
    dyf_filtered = DynamicFrame.fromDF(df_filtered, glueContext, "filter_votes")
    return(DynamicFrameCollection({"CustomTransform0": dyf_filtered}, glueContext))
```

------
#### [ Scala ]

下面的示例采用收到的第一个 `DynamicFrame`，将其转换为 `DataFrame` 以应用本地筛选方法（仅保留拥有超过 1000 票的记录），然后在返回前将其转换回 `DynamicFrame`。

```
object FilterHighVoteCounts {
  def execute(glueContext : GlueContext, input : Seq[DynamicFrame]) : Seq[DynamicFrame] = {
    val frame = input(0).toDF()
    val filtered = DynamicFrame(frame.filter(frame("vote_count") > 1000), glueContext)
    Seq(filtered)
  }
}
```

------

## 编辑自定义转换节点的架构
<a name="transforms-custom-editschema"></a>

使用自定义转换节点时，AWS Glue Studio 无法自动推断由转换创建的输出架构。您可以使用架构编辑器描述由自定义转换代码实现的架构更改。

自定义代码节点可以有任意数量的父节点，每个节点都提供 `DynamicFrame` 作为自定义代码的输入。自定义代码节点会返回 `DynamicFrames`。用作输入的每个 `DynamicFrame` 都具有关联架构。您必须添加架构，描述自定义代码节点返回的每个 `DynamicFrame`。

**注意**  
 当您在自定义转换上设置自己的架构时，AWS Glue Studio 不会沿用上一个节点中的架构。要更新架构，请选择“Custom transform node”（自定义转换节点），然后选择“Data preview”（数据预览）选项卡。生成预览后，选择“Use Preview Schema”（使用预览架构）。该架构随后将会替换为使用预览数据的架构。

**编辑自定义转换节点的架构**

1. 在任务图中选择自定义转换节点后，在节点详细信息面板中，选择 **Output schema (输出架构)** 选项卡。

1. 选择 **Edit (编辑)** 以更改架构。

   如果您有嵌套的数据属性键（如数组或对象），则可以选择 **Expand-Rows (展开行)** 图标（![A double-ended arrow pointing upwards and downwards between two parallel lines](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/expand-rows-icon.png)），展开子数据属性键的列表。选择此图标后，它将更改为 **Collapse-Rows (折叠行)** 图标（![Two arrows, one pointing up to a line and one pointing down to the same line](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/collapse-rows-icon.png)），您可以选择折叠子属性键列表。

1. 使用页面右侧部分中的以下操作修改架构：
   + 要重命名属性键，请将光标放在 **Key (键)** 文本框，然后输入新名称。
   + 要更改属性键的数据类型，请使用列表为属性键选择新数据类型。
   + 要为架构添加新的顶级属性，请选择 **Cancel (取消)** 按钮左侧的 **Overflow (溢出)**（![An ellipsis (...)](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/edit-schema-actions-button.png)）图标，然后选择 **Add root key (添加根键)**。
   + 要将子属性键添加到架构，请选择与父键关联的 **Add-Key (添加键)** 图标 ![A rectangle with a plus sign in the bottom left corner](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/filter-add-icon.png)。输入子键的名称，然后选择数据类型。
   + 要从架构中删除属性键，请选择键名称最右侧的 **Remove (删除)** 图标（![An outline of a trash can](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/delete-icon-black.png)）。

1. 如果您的自定义转换代码使用多个 `DynamicFrames`，您可以添加额外的输出架构。
   + 要添加新的空架构，请选择 **Overflow (溢出)**（![An ellipsis (...)](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/edit-schema-actions-button.png)）图标，然后选择 **Add output schema (添加输出架构)**。
   + 要将现有架构复制到新的输出架构，请确保要复制的架构在架构选择器中显示。选择 **Overflow (溢出)**（![An ellipsis (...)](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/edit-schema-actions-button.png)）图标，然后选择 **Duplicate (重复)**。

   要删除输出架构，请确保要复制的架构在架构选择器中显示。选择 **Overflow (溢出)**（![An ellipsis (...)](http://docs.aws.amazon.com/zh_cn/glue/latest/dg/images/edit-schema-actions-button.png)）图标，然后选择 **Delete (删除)**。

1. 将新的根键添加到新架构或编辑重复的键。

1. 修改输出架构时，请选择 **Apply (应用)** 保存您的更改并退出架构编辑器。

   如果您不想保存更改，请选择 **Cancel (取消)** 按钮。

## 配置自定义转换输出
<a name="transforms-custom-output"></a>

自定义代码转换会返回 `DynamicFrames`，即使结果集中只有一个 `DynamicFrame`。

**处理自定义转换节点的输出**

1. 添加 *SelectFromCollection* 转换节点，该节点将自定义转换节点作为其父节点。更新此转换以指示要使用的数据集。请参阅[使用 SelectFromCollection 选择要保留的数据集](transforms-configure-select-collection.md)了解更多信息。

1. 如果要使用由自定义转换节点生成的其他 `DynamicFrames`，则将其他 *SelectFromCollection* 转换添加任务图。

   考虑以下情况：添加自定义转换节点以将航班数据集拆分为多个数据集，但在每个输出架构中复制某些标识属性键，如航班日期或航班号。为每个输出架构添加 *SelectFromCollection* 转换节点，以自定义转换节点为父节点。

1. （可选）然后，您可以使用每个 *SelectFromCollection* 转换节点作为任务中其他节点的输入，或作为数据目标节点的父节点。