

 从补丁 198 开始，Amazon Redshift 将不再支持创建新的 Python UDF。现有的 Python UDF 将继续正常运行至 2026 年 6 月 30 日。有关更多信息，请参阅[博客文章](https://aws.amazon.com/blogs/big-data/amazon-redshift-python-user-defined-functions-will-reach-end-of-support-after-june-30-2026/)。

# 序列化复杂嵌套 JSON
<a name="serializing-complex-JSON"></a>

本主题演示如何以 JSON 格式序列化嵌套数据。嵌套数据是包含嵌套字段的数据。嵌套字段是指联接在一起作为单个实体的字段，例如数组、结构或对象。

本教程中演示的方法的替代方法是以序列化 JSON 格式查询顶级嵌套集合列。您可以通过 Redshift Spectrum 使用序列化以 JSON 格式检查、转换和摄取嵌套数据。ORC、JSON、Ion 和 Parquet 格式支持此方法。使用会话配置参数 `json_serialization_enable` 配置序列化行为。设置时，复杂的 JSON 数据类型将序列化为 VARCHAR(65535)。嵌套的 JSON 可以通过 [JSON 函数](json-functions.md) 访问。有关更多信息，请参阅 [json\$1serialization\$1enable](r_json_serialization_enable.md)。

例如，如果不设置 `json_serialization_enable`，则以下访问嵌套列的查询直接失败。

```
SELECT * FROM spectrum.customers LIMIT 1;

=> ERROR:  Nested tables do not support '*' in the SELECT clause.

SELECT name FROM spectrum.customers LIMIT 1;

=> ERROR:  column "name" does not exist in customers
```

设置 `json_serialization_enable` 允许直接查询顶级集合。

```
SET json_serialization_enable TO true;

SELECT * FROM spectrum.customers order by id LIMIT 1;

id | name                                 | phones         | orders
---+--------------------------------------+----------------+----------------------------------------------------------------------------------------------------------------------
1  | {"given": "John", "family": "Smith"} | ["123-457789"] | [{"shipdate": "2018-03-01T11:59:59.000Z", "price": 100.50}, {"shipdate": "2018-03-01T09:10:00.000Z", "price": 99.12}]          
 
SELECT name FROM spectrum.customers order by id LIMIT 1;

name
---------
{"given": "John", "family": "Smith"}
```

在序列化嵌套 JSON 时，请考虑以下项目。
+ 当集合列被序列化为 VARCHAR(65535) 时，不能再将其嵌套子字段作为查询语法的一部分直接访问（即在筛选器子句中）。但是，JSON 函数可用于访问嵌套的 JSON。
+ 不支持以下专门化表示：
  + ORC 联合
  + 具有复杂类型键的 ORC 映射
  + Ion 数据报
  + Ion SEXP
+ 时间戳以 ISO 序列化字符串的形式返回。
+ 基本映射键被提升为字符串（例如 `1` 到 `"1"`）。
+ 顶级 null 值被序列化为 NULL。
+ 如果序列化溢出最大 VARCHAR 大小 65535，则单元格将设置为 NULL。

## 序列化包含 JSON 字符串的复杂类型
<a name="serializing-complex-JSON-strings"></a>

预设情况下，嵌套集合中包含的字符串值被序列化为转义 JSON 字符串。当字符串为有效的 JSON 时，转义可能是不可取的。相反，您可能希望直接将嵌套子元素或 VARCHAR 字段编写为 JSON。通过 `json_serialization_parse_nested_strings` 会话级别配置启用此行为。设置 `json_serialization_enable` 和 `json_serialization_parse_nested_strings` 时，有效的 JSON 值将被内联序列化，没有转义字符。当该值是无效的 JSON 时，它会被转义，就好像未设置 `json_serialization_parse_nested_strings` 配置值一样。有关更多信息，请参阅 [json\$1serialization\$1parse\$1nested\$1strings](r_json_serialization_parse_nested_strings.md)。

例如，假设前面示例中的数据包含 JSON 作为 `name` VARCHAR(20) 字段中的 `structs` 复杂类型：

```
name
---------
{"given": "{\"first\":\"John\",\"middle\":\"James\"}", "family": "Smith"}
```

当设置 `json_serialization_parse_nested_strings` 时，`name` 列序列化如下：

```
SET json_serialization_enable TO true;
SET json_serialization_parse_nested_strings TO true;
SELECT name FROM spectrum.customers order by id LIMIT 1;

name
---------
{"given": {"first":"John","middle":"James"}, "family": "Smith"}
```

而不是像这样进行转义：

```
SET json_serialization_enable TO true;
SELECT name FROM spectrum.customers order by id LIMIT 1;

name
---------
{"given": "{\"first\":\"John\",\"middle\":\"James\"}", "family": "Smith"}
```