簡體   English   中英

通過 Terraform 創建的 AWS Glue 中的架構錯誤無效

[英]Invalid Schema error in AWS Glue created via Terraform

我在 Terraform 中有一個 Kinesis Firehose 配置,它從 JSON 中的 Kinesis stream 讀取數據,使用 Glue 將其轉換為 Parquet 並寫入 S3。 數據格式轉換有問題,我收到以下錯誤(刪除了一些細節):

{"attemptsMade":1,"arrivalTimestamp":1624541721545,"lastErrorCode":"DataFormatConversion.InvalidSchema","lastErrorMessage":"模式無效。指定的表沒有列。","attemptEndingTimestamp":1624542026951,"rawData ":"xx","sequenceNumber":"xx","subSequenceNumber":null,"dataCatalogTable":{"catalogId":null,"databaseName":"db_name","tableName":"table_name","region" :null,"versionId":"LATEST","roleArn":"xx"}}

我正在使用的 Glue Table 的 Terraform 配置如下:

resource "aws_glue_catalog_table" "stream_format_conversion_table" {
  name          = "${var.resource_prefix}-parquet-conversion-table"
  database_name = aws_glue_catalog_database.stream_format_conversion_db.name

  table_type = "EXTERNAL_TABLE"

  parameters = {
    EXTERNAL              = "TRUE"
    "parquet.compression" = "SNAPPY"
  }

  storage_descriptor {
    location      = "s3://${element(split(":", var.bucket_arn), 5)}/"
    input_format  = "org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat"
    output_format = "org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat"

    ser_de_info {
      name                  = "my-stream"
      serialization_library = "org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe"

      parameters = {
        "serialization.format" = 1
      }
    }
    columns {
      name = "metadata"
      type = "struct<tenantId:string,env:string,eventType:string,eventTimeStamp:timestamp>"   
    }
    columns {
      name = "eventpayload"
      type = "struct<operation:string,timestamp:timestamp,user_name:string,user_id:int,user_email:string,batch_id:string,initiator_id:string,initiator_email:string,payload:string>"         
    }
  }
}

這里需要改變什么?

我遇到了“架構無效。指定的表沒有列”的組合如下:

  • Glue 架構注冊表中的 avro 架構,
  • 使用“從現有模式添加表”通過控制台創建的粘合表
  • kinesis data firehose 配置了 Parquet 轉換並引用了從架構注冊表創建的膠水表。

事實證明,如果表是從現有架構創建的,則 KDF 無法讀取表的架構。 必須從頭開始創建表(與“從現有模式添加表”相反)這沒有記錄......現在。

除了mberchon的回答之外,我發現 Kinesis Delivery Stream 的默認生成策略不包括實際讀取架構所需的 IAM 權限。

我必須手動修改 IAM 策略以包含glue:GetSchemaglue:GetSchemaVersion

由於不得不手動定義列而感到沮喪,寫了一個 python 工具,它采用了pydantic class(也可以與 json-schema 一起使用)並生成了一個 json,可以與 terraform 一起使用來創建表。

https://github.com/nanit/j2g

from pydantic import BaseModel
from typing import List

class Bar(BaseModel):
    name: str
    age: int

class Foo(BaseModel):
    nums: List[int]
    bars: List[Bar]
    other: str

轉換成

{
 "nums": "array<int>",
 "bars": "array<struct<name:string,age:int>>",
 "other": "string"
}

並且可以像這樣在 terraform 中使用

locals {
  columns = jsondecode(file("${path.module}/glue_schema.json"))
}

resource "aws_glue_catalog_table" "table" {
  name          = "table_name"
  database_name = "db_name"

  storage_descriptor {
    dynamic "columns" {
      for_each = local.columns

      content {
        name = columns.key
        type = columns.value
      }
    }
  }
}

因為我遇到了同樣的問題並找到了一個似乎有效的解決方法,所以我在這里發帖。

如上所述,AWS 不允許您使用從現有模式生成的表來使用 Firehose 轉換數據類型。 也就是說,如果您使用的是 terraform,則可以使用現有模式創建表,然后使用創建的第一個表中的列屬性創建另一個表,然后使用第二個表作為流水配置中數據類型轉換的表,我可以確認這個作品。

表 terraform:

resource "aws_glue_catalog_table" "aws_glue_catalog_table_from_schema" {
  name          = "first_table"
  database_name = "foo"
  storage_descriptor {
    schema_reference {
      schema_id {
        schema_arn = aws_glue_schema.your_glue_schema.arn
      }
      schema_version_number = aws_glue_schema.your_glue_schema.latest_schema_version
    }
  }
}

resource "aws_glue_catalog_table" "aws_glue_catalog_table_from_first_table" {
  name          = "second_table"
  database_name = "foo"
  storage_descriptor {
    dynamic "columns" {
      for_each = aws_glue_catalog_table.aws_glue_catalog_table_from_schema.storage_descriptor[0].columns
      content {
        name = columns.value.name
        type = columns.value.type
      }
    }
  }
}

firehose數據格式轉換配置:

data_format_conversion_configuration {
  output_format_configuration{
    serializer {
      parquet_ser_de {}
    }
  }
  input_format_configuration {
    deserializer {
      hive_json_ser_de {}
    }
  }
  schema_configuration {
    database_name = aws_glue_catalog_table.aws_glue_catalog_table_from_first_table.database_name
    role_arn      = aws_iam_role.firehose_role.arn
    table_name    = aws_glue_catalog_table.aws_glue_catalog_table_from_first_table.name
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM