AWS SAM模板DataFormatConversion.InvalidSchema错误:Glue表有列却报错
在AWS CloudFormation的SAM模板中定义了Glue::Table和KinesisFirehose::DeliveryStream,S3输出桶生成错误文件,错误信息如下:
"errorCode":"DataFormatConversion.InvalidSchema","errorMessage":"The schema is invalid. The specified table has no columns."
但查看Glue表时能正常看到列,请问该错误的可能原因是什么?
相关模板关键内容
# template.yaml # Resources: ... myTable: Type: AWS::Glue::Table Properties: ... CatalogId: !Ref AWS::AccountId DatabaseName: myDatabase TableInput: Name: myTable StorageDescriptor: SchemaReference: SchemaVersionId: !GetAtt mySchema.InitialSchemaVersionId mySchema: Type: AWS::Glue::Schema Properties: ... CheckpointVersion: IsLatest: true VersionNumber: 1 Compatibility: BACKWARD DataFormat: AVRO Name: myTable SchemaDefinition: | { "type": "record", "namespace": "myDatabase", "name": "myTable", "fields": [ { "name": "field1", "type": "string" }, { "name": "field2", "type": "int" } ] } myDeliveryStream: Type: AWS::KinesisFirehose::DeliveryStream Properties: ExtendedS3DestinationConfiguration: ... SchemaConfiguration: Region: eu-central-1 DatabaseName: myDatabase TableName: myTable CatalogId: !Ref AWS::AccountId VersionId: "0" RoleARN: !GetAtt FirehoseAccessRole.Arn
Firehose指定的Schema版本ID错误
模板里DeliveryStream的SchemaConfiguration硬编码了VersionId: "0",但Glue Schema的初始版本ID是系统自动生成的字符串(不是固定的"0"),和创建表时用的!GetAtt mySchema.InitialSchemaVersionId完全不一致。Firehose用错误的版本ID查询时,找不到对应Schema,就会返回“表无列”的错误。
解决:把DeliveryStream中SchemaConfiguration的VersionId改成!GetAtt mySchema.InitialSchemaVersionId,和Glue Table引用的版本保持统一。资源创建顺序存在竞态
虽然CloudFormation会自动处理依赖,但如果DeliveryStream在Glue Table和Schema完全完成元数据同步前就启动,可能会临时读取到“无列”的状态。
解决:在DeliveryStream的属性里显式添加依赖:myDeliveryStream: Type: AWS::KinesisFirehose::DeliveryStream DependsOn: [myTable, mySchema] Properties: ...确保Table和Schema彻底创建完成后,再部署Firehose。
Glue Table未同步Schema列信息
仅通过SchemaReference关联Schema时,偶尔会出现Glue Table的元数据未及时同步列的情况(比如后台同步延迟),导致Firehose读取时看不到列。
解决:在Glue Table的StorageDescriptor里显式添加列定义,和Schema保持一致:myTable: Properties: TableInput: StorageDescriptor: SchemaReference: SchemaVersionId: !GetAtt mySchema.InitialSchemaVersionId Columns: - Name: field1 Type: string - Name: field2 Type: int这样即使SchemaReference同步有问题,表本身也有明确的列信息。
Firehose角色权限不足
如果Firehose使用的FirehoseAccessRole没有读取Glue Schema和Table元数据的权限,也会导致无法获取列信息,返回错误。
解决:给角色添加以下权限策略:{ "Effect": "Allow", "Action": [ "glue:GetTable", "glue:GetSchemaVersion", "glue:GetSchema" ], "Resource": [ "arn:aws:glue:eu-central-1:${AWS::AccountId}:database/myDatabase", "arn:aws:glue:eu-central-1:${AWS::AccountId}:table/myDatabase/myTable", "arn:aws:glue:eu-central-1:${AWS::AccountId}:schema/myDatabase/myTable/*" ] }
内容的提问来源于stack exchange,提问作者Gabriele

