我在Kafka中有几个主题正在将AVRO文件写入S3存储桶,我想使用AWS Athena对存储桶执行一些查询。
我正在尝试创建表,但是AWS Glue搜寻器会运行并且不会添加我的表(如果我将文件类型更改为JSON,它将起作用)。我试图从Athena控制台创建一个表,但是它不显示对AVRO文件的支持。
关于如何使其工作的任何想法?
答案 0 :(得分:0)
我建议手动而不是通过胶水进行。不幸的是,胶水仅适用于最基本的情况。
您可以在以下位置找到有关如何创建Avro表的文档:https://docs.aws.amazon.com/athena/latest/ug/avro.html
Avro表的警告是,您需要同时指定表列和Avro模式。这看起来很奇怪和多余,但这就是Athena / Presto的工作方式。它需要一个架构来知道如何解释文件,然后需要知道文件中哪些属性要公开为列(以及它们的类型,它们可能与Avro类型匹配,也可能不匹配)。
CREATE EXTERNAL TABLE avro_table (
foo STRING,
bar INT
)
ROW FORMAT
SERDE 'org.apache.hadoop.hive.serde2.avro.AvroSerDe'
WITH SERDEPROPERTIES ('avro.schema.literal' = '
{
"type": "record",
"name": "example",
"namespace": "default",
"fields": [
{
"name": "foo",
"type": ["null", "string"],
"default": null
},
{
"name": "bar",
"type": ["null", "int"],
"default": null
}
]
}
')
STORED AS AVRO
LOCATION 's3://some-bucket/data/';
请注意,Avro模式如何在SERDE属性值(单引号)内显示为JSON文档–格式是可选的,但使此示例易于阅读。
答案 1 :(得分:-1)
手动执行似乎是使其工作的一种方式。
这是一些直接从文字avro模式生成Athena模式的代码。它适用于avro-python3
上的python3.7
。它是从这里获取的:https://github.com/dataqube-GmbH/avro2athena(我是仓库的所有者)
from avro.schema import Parse, RecordSchema, PrimitiveSchema, ArraySchema, MapSchema, EnumSchema, UnionSchema, FixedSchema
def create_athena_schema_from_avro(avro_schema_literal: str) -> str:
avro_schema: RecordSchema = Parse(avro_schema_literal)
column_schemas = []
for field in avro_schema.fields:
column_name = field.name.lower()
column_type = create_athena_column_schema(field.type)
column_schemas.append(f"`{column_name}` {column_type}")
return ', '.join(column_schemas)
def create_athena_column_schema(avro_schema) -> str:
if type(avro_schema) == PrimitiveSchema:
return rename_type_names(avro_schema.type)
elif type(avro_schema) == ArraySchema:
items_type = create_athena_column_schema(avro_schema.items)
return f'array<{items_type}>'
elif type(avro_schema) == MapSchema:
values_type = avro_schema.values.type
return f'map<string,{values_type}>'
elif type(avro_schema) == RecordSchema:
field_schemas = []
for field in avro_schema.fields:
field_name = field.name.lower()
field_type = create_athena_column_schema(field.type)
field_schemas.append(f'{field_name}:{field_type}')
field_schema_concatenated = ','.join(field_schemas)
return f'struct<{field_schema_concatenated}>'
elif type(avro_schema) == UnionSchema:
# pick the first schema which is not null
union_schemas_not_null = [s for s in avro_schema.schemas if s.type != 'null']
if len(union_schemas_not_null) > 0:
return create_athena_column_schema(union_schemas_not_null[0])
else:
raise Exception('union schemas contains only null schema')
elif type(avro_schema) in [EnumSchema, FixedSchema]:
return 'string'
else:
raise Exception(f'unknown avro schema type {avro_schema.type}')
def rename_type_names(typ: str) -> str:
if typ in ['long']:
return 'bigint'
else:
return typ