tjh*_*in1 6 aws-cloudformation aws-cli terraform amazon-athena terraform-provider-aws
您可以在Amazon Athena中创建视图吗?概述了如何使用用户界面创建视图。
我想以编程方式创建一个AWS Athena View,理想情况下使用Terraform(称为CloudFormation)创建。
我遵循此处概述的步骤:https : //ujjwalbhardwaj.me/post/create-virtual-views-with-aws-glue-and-query-them-using-athena,但是我遇到了一个问题视图很快就会过时。
...._view' is stale; it must be re-created.
terraform代码如下所示:
resource "aws_glue_catalog_table" "adobe_session_view" {
database_name = "${var.database_name}"
name = "session_view"
table_type = "VIRTUAL_VIEW"
view_original_text = "/* Presto View: ${base64encode(data.template_file.query_file.rendered)} */"
view_expanded_text = "/* Presto View */"
parameters = {
presto_view = "true"
comment = "Presto View"
}
storage_descriptor {
ser_de_info {
name = "ParquetHiveSerDe"
serialization_library = "org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe"
}
columns { name = "first_column" type = "string" }
columns { name = "second_column" type = "int" }
...
columns { name = "nth_column" type = "string" }
}
Run Code Online (Sandbox Code Playgroud)
我很乐意使用的替代方法是AWS CLI,但是aws athena [option]对此没有任何选择。
我试过了:
JD *_*D D 12
正如您所建议的,绝对可以通过 AWS CLI 使用start-query-execution. 正如您所指出的,这确实需要您为结果提供 S3 位置,即使您不需要检查文件(Athena 会出于某种原因在该位置放置一个空的 txt 文件)。
下面是一个例子:
$ aws athena start-query-execution --query-string "create view my_view as select * from my_table" --result-configuration "OutputLocation=s3://my-bucket/tmp" --query-execution-context "Database=my_database"
{
"QueryExecutionId": "1744ed2b-e111-4a91-80ea-bcb1eb1c9c25"
}
Run Code Online (Sandbox Code Playgroud)
您可以通过创建工作组并在那里设置位置来避免让客户端指定存储桶。
您可以使用该get-query-execution命令检查您的视图创建是否成功。
$ aws --region athena get-query-execution --query-execution-id bedf3eba-55b0-42de-9a7f-7c0ba71c6d9b
{
"QueryExecution": {
"QueryExecutionId": "1744ed2b-e111-4a91-80ea-bcb1eb1c9c25",
"Query": "create view my_view as select * from my_table",
"StatementType": "DDL",
"ResultConfiguration": {
"OutputLocation": "s3://my-bucket/tmp/1744ed2b-e111-4a91-80ea-bcb1eb1c9c25.txt"
},
"Status": {
"State": "SUCCEEDED",
"SubmissionDateTime": 1558744806.679,
"CompletionDateTime": 1558744807.312
},
"Statistics": {
"EngineExecutionTimeInMillis": 548,
"DataScannedInBytes": 0
},
"WorkGroup": "primary"
}
}
Run Code Online (Sandbox Code Playgroud)
小智 7
更新 Terraform 0.12+ 语法的上述示例,并添加从文件系统读取视图查询:
resource "null_resource" "athena_views" {
for_each = {
for filename in fileset("${path.module}/athenaviews/", "**"):
replace(filename,"/","_") => file("${path.module}/athenaviews/${filename}")
}
provisioner "local-exec" {
command = <<EOF
aws athena start-query-execution \
--output json \
--query-string CREATE OR REPLACE VIEW ${each.key} AS ${each.value} \
--query-execution-context "Database=${var.athena_database}" \
--result-configuration "OutputLocation=s3://${aws_s3_bucket.my-bucket.bucket}"
EOF
}
provisioner "local-exec" {
when = "destroy"
command = <<EOF
aws athena start-query-execution \
--output json \
--query-string DROP VIEW IF EXISTS ${each.key} \
--query-execution-context "Database=${var.athena_database}" \
--result-configuration "OutputLocation=s3://${aws_s3_bucket.my-bucket.bucket}"
EOF
}
}
Run Code Online (Sandbox Code Playgroud)
还要注意然后when= "destroy"阻止以确保在您的堆栈被拆除时删除视图。
将带有 SELECT 查询的文本文件放在目录(在此示例中为 athenaview/ )下的模块路径下,它将拾取它们并创建视图。这将创建名为 的视图subfolder_filename,并在删除文件时销毁它们。
没有文档记录在雅典娜中以编程方式创建视图,并且不受支持,但是可以实现。使用创建视图时,幕后发生的事情StartQueryExecution是Athena让Presto创建视图,然后提取Presto的内部表示并将其放入Glue目录中。
陈旧性问题通常来自Presto元数据中的列和Glue元数据不同步。Athena视图实际上包含对该视图的三个描述:视图SQL,Glue格式的列及其类型,以及Presto格式的列和类型。如果其中任何一个不同步,您将得到“…已陈旧;必须重新创建它”。错误。
这些是在胶水表上用作雅典娜视图的要求:
TableType 一定是 VIRTUAL_VIEWParameters 必须包含 presto_view: trueTableInput.ViewOriginalText 必须包含编码的Presto视图(请参见下文)StorageDescriptor.SerdeInfo 必须为空地图StorageDescriptor.Columns 必须包含视图定义的所有列及其类型棘手的部分是编码的Presto视图。该结构是通过以下代码创建的:https : //github.com/prestosql/presto/blob/27a1b0e304be841055b461e2c00490dae4e30a4e/presto-hive/src/main/java/io/prestosql/plugin/hive/HiveUtil.java#L597-L600,这或多或少是它的作用:
/* Presto View:(后面有一个空格:)*/(之前有一个空格*)描述视图的JSON如下所示:
catalog必须具有的价值属性awsdatacatalog。schema属性,必须是在视图中创建(即,其必须在匹配数据库的名称DatabaseName周边胶结构的属性。name和typeoriginalSql实际视图SQL财产(不包括CREATE VIEW …,它应该开始SELECT …或WITH …)这是一个例子:
{
"catalog": "awsdatacatalog",
"schema": "some_database",
"columns": [
{"name": "col1", "type": "varchar"},
{"name": "col2", "type": "bigint"}
],
"originalSql": "SELECT col1, col2 FROM some_other_table"
}
Run Code Online (Sandbox Code Playgroud)
需要注意的是,列的类型几乎与Glue中的名称相同,但并不完全相同。如果Athena / Glue string在此JSON中的值必须为varchar。如果Athena / Glue使用array<string>此JSON中的值,则必须为array(varchar),并且struct<foo:int>变为row(foo int)。
这很混乱,将它们放在一起需要一些摆弄和测试。使它正常工作的最简单方法是创建一些视图并向后解码上面的指令以查看它们的外观,然后尝试自己进行操作。
根据之前的答案,这里有一个示例,仅当源文件已更改时才执行查询。也不是将 SQL 查询粘贴到命令中,而是使用file://适配器将其传递给 AWS CLI 命令。
resource "null_resource" "views" {
for_each = {
for filename in fileset("${var.sql_files_dir}/", "**/*.sql") :
replace(replace(filename, "/", "_"), ".sql", "") => "${var.sql_files_dir}/${filename}"
}
triggers = {
md5 = filemd5(each.value)
# External references from destroy provisioners are not allowed -
# they may only reference attributes of the related resource.
database_name = var.database_name
s3_bucket_query_output = var.s3_bucket_query_output
}
provisioner "local-exec" {
command = <<EOF
aws athena start-query-execution \
--output json \
--query-string file://${each.value} \
--query-execution-context "Database=${var.database_name}" \
--result-configuration "OutputLocation=s3://${var.s3_bucket_query_output}"
EOF
}
provisioner "local-exec" {
when = destroy
command = <<EOF
aws athena start-query-execution \
--output json \
--query-string 'DROP VIEW IF EXISTS ${each.key}' \
--query-execution-context "Database=${self.triggers.database_name}" \
--result-configuration "OutputLocation=s3://${self.triggers.s3_bucket_query_output}"
EOF
}
}
Run Code Online (Sandbox Code Playgroud)
为了使销毁工作正确,命名文件与文件名完全相同 -example.sql与查询相关:
CREATE OR REPLACE VIEW example AS ...
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1011 次 |
| 最近记录: |