![](/img/trans.png)
[英]aws_glue_trigger in terraform creates invalid expression schedule in aws
[英]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>"
}
}
}
這里需要改變什么?
我遇到了“架構無效。指定的表沒有列”的組合如下:
事實證明,如果表是從現有架構創建的,則 KDF 無法讀取表的架構。 必須從頭開始創建表(與“從現有模式添加表”相反)這沒有記錄......現在。
由於不得不手動定義列而感到沮喪,寫了一個 python 工具,它采用了pydantic
class(也可以與 json-schema 一起使用)並生成了一個 json,可以與 terraform 一起使用來創建表。
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.