如何解决 Redshift Spectrum 中的数据不兼容错误?

上次更新时间:2020 年 10 月 15 日

我正在尝试在 Amazon Redshift Spectrum 中使用外部 schema、对象或文件格式。但是我收到了错误提示。如何排查这些错误?

解决方法

数据格式不兼容错误

要解决 Redshift Spectrum 中的数据格式不兼容错误,请执行以下步骤:

1.    从 SVL_S3LOG 系统视图中检索完整的错误消息:

select * from SVL_S3LOG where query = '<query_ID_of_the_Spectrum_query>';

不兼容的 Parquet schema 中的不匹配会产生以下错误消息:

File 'https://s3bucket/location/file has an incompatible Parquet schema for column ‘s3://s3bucket/location.col1'. Column type: VARCHAR, Par...

2.    检查 Message(消息)列以查看错误说明。该错误说明解释了 Redshift Spectrum 与外部文件之间的数据不兼容性。

3.    检查外部文件的 schema,然后将其与 CREATE EXTERNAL TABLE 定义中的列定义进行比较。

4.    (可选)如果 Apache Parquet 文件中的列定义与外部表不同,请修改外部表中的列定义。列定义必须与 Apache Parquet 文件的列式文件格式匹配。

5.    对 SVV_EXTERNAL_COLUMNS 视图运行以下查询:

select * from SVV_EXTERNAL_COLUMNS where schemaname = '<ext_schema_name>' and tablename = '<ext_table_name>';

此查询将检查 CREATE EXTERNAL TABLE 定义中列的数据类型。

注意:对于像 Apache Parquet 这样的列式文件格式,列类型嵌入在数据中。CREATE EXTERNAL TABLE 定义中的列类型必须与数据文件的列类型匹配。列定义不匹配会导致数据不兼容错误。

类型长度无效错误

如果您选择的 Redshift Spectrum 表包含数据类型为 DECIMAL 的列,则可能会遇到以下错误:

S3 Query Exception (Fetch). Task failed due to an internal error. File ‘https://s3.amazonaws.com/…/<file_name>’ has an incompatible Parquet schema for column ‘<column_name>’
column ‘<column_name>’ has an invalid type length

要解决 Redshift Spectrum 中的类型长度无效错误,请使用外部表定义。表定义必须与外部文件中定义的“precision”和“scale”值匹配。例如:

create external table ext_schema.tablename (c1 int, c2 decimal (6,2)) stored as PARQUET location 's3://.../.../';

在此示例中,“precision”和“Scale”值的更新值(在 c2 decimal 列中)分别设置为 6 和 2。因此,c2 列中列出的 CREATE EXTERNAL TABLE 定义值必须与 Apache Parquet 文件中定义的值匹配。

内部错误

如果您从 Amazon Athena 目录中选择一个外部 schema,则可能会在 Redshift Spectrum 中收到以下错误:

Task failed due to an internal error. File 'https://s3...snappy.parquet  has an incompatible Parquet schema for column 's3://.../tbl.a'. Column type: BOOLEAN, Parquet schema:\noptional int32 b [i:26 d:1 r:0]

在 Redshift Spectrum 中,CREATE EXTERNAL TABLE 中的列顺序必须与 Parquet 文件中字段的顺序匹配。对于 Apache Parquet 文件,所有文件都必须具有与外部表定义中相同的字段顺序。如果您忽略此排序或重新排列任何数据类型列,则会收到内部错误。

注意:虽然您可以将 Amazon Athena 数据目录导入到 Redshift Spectrum 中,但在 Redshift Spectrum 中可能无法正常运行查询。在 Redshift Spectrum 中,列名称与 Apache Parquet 文件字段匹配。同时,Amazon Athena 使用列名称映射到 Apache Parquet 文件中的字段。

要解决内部错误,请在 SELECT 语句中指定以下列名称:

select col_1, col_2, col_3, .... col_n from athena_schema.tablename;

此外,请确保 AWS Identity and Access Management (IAM) 角色允许访问 Amazon Athena。有关更多信息,请参阅 Amazon Redshift Spectrum 的 IAM 策略

列类型无效错误

如果您使用 Redshift Spectrum 从 AWS Glue 数据目录表中查询 VARCHAR 数据类型列,则可能会收到以下错误:

<column_name> - Invalid column type for column <column_name>. Type: varchar"

AWS Glue 和 Redshift Spectrum 都支持 VARCHAR 数据类型。但是,AWS Glue 目录定义的 VARCHAR 数据类型不包含大小参数(如 VARCHAR (256))。当 Redshift Spectrum 查询一个在定义时未包含大小参数的 VARCHAR 列时,就会出现列类型无效错误。

要解决列类型无效错误,请执行以下步骤:

1.    运行以下 AWS 命令行界面 (AWS CLI) 语法以检索 AWS Glue 表数据并将其存储在本地文件中:

aws glue get-table --region us-east-1 --database gluedb --name click_data_json > click-data-table.json

注意:如果在运行 AWS CLI 命令时收到错误,请确保使用的是最新版本的 AWS CLI

2.    使用任意文本编辑器打开 click-data-table.json 文件,并删除外部 {"Table": ...} 信封。例如,更新后的配置现在应如下所示:

{"Name": "my-table", ...}

3.    删除 UpdateTable 操作中不允许的任何字段。例如,您可以删除以下字段:
DatabaseName
Owner
CreateTime
UpdateTime
LastAccessTime
CreatedBy
IsRegisteredWithLakeFormation.

4.    使用所需的大小参数将 STRING 列类型修改为“varchar”。例如:

"Type": "varchar(1000)"

5.    使用以下命令语法更新 AWS Glue 表:

aws glue update-table --region us-east-1 --database gluedb --table-input "$(cat click-data-table.json)"

6.    在 AWS Glue 中检查表定义,并验证数据类型是否已修改。

7.    在 Amazon Redshift 中查询 AWS Glue 表中的外部 schema。例如:

create external schema glue_schema from data catalog database ‘gluedb’ iam_role 'arn:aws:iam::111111111111:role/myRedshiftRole' region 'us-east-1';

8.    为 click_data_json 运行以下查询:

select * from glue_schema.click_data_json;

这篇文章对您有帮助吗?


您是否需要账单或技术支持?