使用 COPY 将数据加载到 SUPER 列 - Amazon Redshift
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

从 2025 年 11 月 1 日起,Amazon Redshift 将不再支持创建新的 Python UDF。如果您想要使用 Python UDF,请在该日期之前创建 UDF。现有的 Python UDF 将继续正常运行。有关更多信息,请参阅博客文章

使用 COPY 将数据加载到 SUPER 列

在以下部分中,您可以了解使用 COPY 命令将 JSON 数据加载到 Amazon Redshift 的不同方法。有关 Amazon Redshift 用于解析 COPY 命令中 JSON 的数据格式参数的信息,请阅读数据格式参数中的JSON format for COPY参数描述。

从 JSON 和 Avro 复制数据

Amazon Redshift 提供了以下使用 COPY 摄取 JSON 文档的方法,甚至是对于完全或部分未知的 JSON 结构:

  • 使用 noshred 选项将从 JSON 文档派生的数据存储到单个 SUPER 数据列中。当 schema 未知或预计将更改时,此方法非常有用。因此,此方法可以更容易地将整个元组存储在单个 SUPER 列中。

  • 使用 autojsonpaths 选项将 JSON 文档分解为多个 Amazon Redshift 列。属性可以是 Amazon Redshift 标量或 SUPER 值。

您可以将这些选项与 JSON 或 Avro 格式一起使用。有关 JSON 选项(例如 noshredautojsonpaths)的更多信息,请参阅JSON format for COPY

Amazon Redshift 中 JSON 对象的最大大小为 4 MB,这在任何分解或解析之前适用。

方法 1:使用 noshred 将 JSON 文档复制到单个 SUPER 数据列

可以在 COPY 命令中使用 noshred 选项将整个 JSON 文档复制到单个 SUPER 数据列。考虑以下示例:

  1. 创建包含单个 SUPER 数据列的表。

    CREATE TABLE region_nations_noshred (rdata SUPER);
  2. 将 Amazon S3 中的数据复制到单个 SUPER 数据列中。要将 JSON 源数据摄取到单个 SUPER 数据列中,请在 FORMAT JSON 子句中指定 noshred 选项。

    COPY region_nations_noshred FROM 's3://redshift-downloads/semistructured/tpch-nested/data/json/region_nation' REGION 'us-east-1' IAM_ROLE 'arn:aws:iam::xxxxxxxxxxxx:role/Redshift-S3' FORMAT JSON 'noshred';

    在 COPY 成功摄取 JSON 后,您的表具有包含整个 JSON 对象数据的 rdata SUPER 数据列。摄取的数据将维护 JSON 层次结构的所有属性。但是,叶子会转换为 Amazon Redshift 标量类型,以实现高效的查询处理。

  3. 使用以下查询检索原始 JSON 字符串。

    SELECT rdata FROM region_nations_noshred;

    当 Amazon Redshift 生成一个 SUPER 数据列时,它可以通过 JSON 序列化使用 JDBC 作为字符串进行访问。有关更多信息,请参阅 序列化复杂嵌套 JSON

方法 2:将 JSON 文档复制到多个 SUPER 数据列

您可以将 JSON 文档拆分为多个列,这些列可以是 SUPER 数据列或 Amazon Redshift 标量类型。Amazon Redshift 会将 JSON 对象的不同部分分布到不同的列。考虑以下示例:

  1. 创建包含多列的表来保存分解的 JSON。

    CREATE TABLE region_nations ( r_regionkey smallint ,r_name varchar ,r_comment varchar ,r_nations super );
  2. 要将 JSON 复制到 region_nations 表,请在 FORMAT JSON 子句中指定 AUTO 选项,以将 JSON 值拆分到多个列中。COPY 将顶级 JSON 属性与列名匹配,并允许嵌套值作为 SUPER 值(如 JSON 数组和对象)摄取。

    COPY region_nations FROM 's3://redshift-downloads/semistructured/tpch-nested/data/json/region_nation' REGION 'us-east-1' IAM_ROLE 'arn:aws:iam::xxxxxxxxxxxx:role/Redshift-S3' FORMAT JSON 'auto';

    当 JSON 属性名称混合使用大小写时,请在 FORMAT JSON 子句中指定 auto ignorecase 选项。有关 COPY 命令的更多信息,请参阅使用“auto ignorecase”选项从 JSON 数据中加载

在某些情况下,列名和 JSON 属性之间存在不匹配的情况,或者要加载的属性嵌套超过一层深度。如果是这样,请使用 jsonpaths 文件将 JSON 属性手动映射到 Amazon Redshift 列。考虑以下示例:

  1. 创建包含多列的表来保存分解的 JSON。

    CREATE TABLE region_nations ( r_regionkey smallint ,r_name varchar ,r_comment varchar ,r_nations super );
  2. 在这种情况下,列名称与 JSON 属性不匹配。可以创建一个 jsonpaths 文件,该文件将属性的路径按其在 jsonpaths 数组中的位置映射到表列,如下所示:

    {"jsonpaths": [ "$.r_regionkey", "$.r_name", "$.r_comment", "$.r_nations ] }
  3. 使用 jsonpaths 文件的位置作为 COPY 中 FORMAT JSON 选项的参数。

    COPY nations FROM 's3://redshift-downloads/semistructured/tpch-nested/data/json/region_nation' REGION 'us-east-1' IAM_ROLE 'arn:aws:iam::xxxxxxxxxxxx:role/Redshift-S3' FORMAT JSON 's3://redshift-downloads/semistructured/tpch-nested/data/jsonpaths/nations_jsonpaths.json';
  4. 使用以下查询可访问显示传播到多个列的数据的表。使用 JSON 格式打印 SUPER 数据列。

    SELECT r_regionkey,r_name,r_comment,r_nations[0].n_nationkey FROM region_nations ORDER BY 1,2,3 LIMIT 1;

jsonpaths 文件将 JSON 文档中的字段映射到表列。您可以提取其它列,例如分配键和排序键,同时仍将完整文档作为 SUPER 列加载。以下查询将完整文档加载到 nations 列。name 列为排序键,而 regionkey 列为分配键。考虑以下示例:

  1. 创建包含多列的表来保存分解的 JSON。

    CREATE TABLE nations_sorted ( regionkey smallint, name varchar, nations super ) DISTKEY(regionkey) SORTKEY(name);
  2. 将根 jsonpath“$”映射到文档的根目录,如下所示:

    {"jsonpaths": [ "$.r_regionkey", "$.r_name", "$" ] }
  3. 使用 jsonpaths 文件的位置作为 COPY 中 FORMAT JSON 选项的参数。

    COPY nations_sorted FROM 's3://redshift-downloads/semistructured/tpch-nested/data/json/region_nation' REGION 'us-east-1' IAM_ROLE 'arn:aws:iam::xxxxxxxxxxxx:role/Redshift-S3' FORMAT JSON 's3://redshift-downloads/semistructured/tpch-nested/data/jsonpaths/nations_sorted_jsonpaths.json';

有关使用 jsonpaths 的更多信息,请参阅从 JSON 格式数据执行的 COPY 操作

从文本和 CSV 复制数据

Amazon Redshift 将文本和 CSV 格式的 SUPER 列表示为序列化 JSON。要使用正确的类型信息加载 SUPER 列,则需要有效的 JSON 格式。取消引用对象、数组、数字、布尔值和空值。用双引号将字符串值括起来。SUPER 列对文本和 CSV 格式使用标准转义规则。

当从 CSV 格式进行复制时,分隔符将根据 CSV 标准进行转义。考虑以下示例:

CREATE TABLE region_nations ( r_regionkey smallint ,r_name varchar ,r_comment varchar ,r_nations super ); COPY region_nations FROM 's3://redshift-downloads/semistructured/tpch-nested/data/csv/region_nation' REGION 'us-east-1' IAM_ROLE 'arn:aws:iam::xxxxxxxxxxxx:role/Redshift-S3' FORMAT CSV;

当从文本进行复制时,如果选定的分隔符也可能出现在 SUPER 字段中,请在 COPY 和 UNLOAD 期间使用 ESCAPE 选项。考虑以下示例:

CREATE TABLE region_nations ( r_regionkey smallint ,r_name varchar ,r_comment varchar ,r_nations super ); COPY region_nations FROM 's3://redshift-downloads/semistructured/tpch-nested/data/text/region_nation' REGION 'us-east-1' IAM_ROLE 'arn:aws:iam::xxxxxxxxxxxx:role/Redshift-S3' DELIMITER ',' ESCAPE;

从列格式的 Parquet 和 ORC 中复制数据

如果半结构化或嵌套数据已经以 Apache Parquet 或 Apache ORC 格式提供,则可以使用 COPY 命令将数据摄取到 Amazon Redshift 中。

Amazon Redshift 表格结构应与 Parquet 或 ORC 文件的列数和列数据类型相匹配。通过在 COPY 命令中指定 SERIALIZETOJSON,您可以将文件中与表中的 SUPER 列对齐的任何列类型加载为 SUPER。这包括结构和数组类型。

以下示例使用 Parquet 格式:

COPY region_nations FROM 's3://redshift-downloads/semistructured/tpch-nested/data/parquet/region_nation' REGION 'us-east-1' IAM_ROLE 'arn:aws:iam::xxxxxxxxxxxx:role/Redshift-S3' FORMAT PARQUET SERIALIZETOJSON;

以下示例使用 ORC 格式。

COPY region_nations FROM 's3://redshift-downloads/semistructured/tpch-nested/data/orc/region_nation' IAM_ROLE 'arn:aws:iam::xxxxxxxxxxxx:role/Redshift-S3' FORMAT ORC SERIALIZETOJSON;

当日期或时间数据类型的属性位于 ORC 中时,Amazon Redshift 会在 SUPER 中对它们进行编码时将其转换为 varchar。