繁体   English   中英

使用 Cloud Formation 模板创建 AWS Athena 视图

[英]Creating AWS Athena View using Cloud Formation template

是否可以通过 cloudformation 模板创建 Athena 视图。 我可以使用 Athena Dashboard 创建视图,但我想使用 CF 模板以编程方式执行此操作。 在 AWS 文档中找不到任何详细信息,因此不确定是否受支持。

谢谢。

通常,CloudFormation 用于以可重复的方式部署基础设施。 这并不是一个数据库,它通常单独一直持续到其它基础设施里面同样也适用于数据。

对于 Amazon Athena,AWS CloudFormation 仅支持:

  • 数据目录
  • 命名查询
  • 工作组

最接近您的要求的是Named Query ,它(我认为)可以存储可以创建视图的查询(例如CREATE VIEW... )。

请参阅: AWS::Athena::NamedQuery - AWS CloudFormation

更新: @Theo 指出 AWS CloudFormation 还具有 AWS Glue 功能,包括:

  • AWS::Glue::Table

这显然可用于创建视图。 请参阅下面的评论。

可以使用 CloudFormation 创建视图,只是非常非常复杂。 Athena 视图存储在 Glue 数据目录中,就像数据库和表一样。 实际上,Athena 视图是 Glue Data Catalog 中的表,只是内容略有不同。

有关如何以编程方式创建视图的完整描述,请参阅此答案,您将了解复杂性:以编程方式创建 AWS Athena 视图- 可以将其映射到 CloudFormation,但我不建议这样做。

如果要使用 CloudFormation 创建数据库和表,资源为AWS::Glue::DatabaseAWS::Glue::Table

我认为目前从CloudFormation模板创建Athena视图的最佳方法是使用自定义资源和 Lambda。 我们必须提供视图创建和删除的方法。 例如,可以定义使用crhelper库 Lambda:

from __future__ import print_function
from crhelper import CfnResource
import logging
import os
import boto3

logger = logging.getLogger(__name__)
helper = CfnResource(json_logging=False, log_level='DEBUG', boto_level='CRITICAL', sleep_on_delete=120)

try:
    client = boto3.client('athena')
    ATHENA_WORKGROUP = os.environ['athena_workgroup']
    DATABASE = os.environ['database']
    QUERY_CREATE = os.environ['query_create']
    QUERY_DROP = os.environ['query_drop']
except Exception as e:
    helper.init_failure(e)

@helper.create
@helper.update
def create(event, context):
    logger.info("View creation started")

    try:
        executionResponse = client.start_query_execution(
            QueryString=QUERY_CREATE,
            QueryExecutionContext={'Database': DATABASE},
            WorkGroup='AudienceAthenaWorkgroup'
        )
        logger.info(executionResponse)

        response = client.get_query_execution(QueryExecutionId=executionResponse['QueryExecutionId'])
        logger.info(response)

        if response['QueryExecution']['Status']['State'] == 'FAILED':
            logger.error("Query failed")
            raise ValueError("Query failed")

        helper.Data['success'] = True
        helper.Data['id'] = executionResponse['QueryExecutionId']
        helper.Data['message'] = 'query is running'

    except Exception as e:
        print(f"An exception occurred: {e}")

    if not helper.Data.get("success"):
        raise ValueError("Creating custom resource failed.")

    return


@helper.delete
def delete(event, context):
    logger.info("View deletion started")

    try:
        executionResponse = client.start_query_execution(
            QueryString=QUERY_DROP,
            QueryExecutionContext={'Database': DATABASE},
            WorkGroup='AudienceAthenaWorkgroup'
        )
        logger.info(executionResponse)

    except Exception as e:
        print("An exception occurred")
        print(e)

@helper.poll_create
def poll_create(event, context):
    logger.info("Pol creation")

    response = client.get_query_execution(QueryExecutionId=event['CrHelperData']['id'])

    logger.info(f"Poll response: {response}")

    # There are 3 types of state of query
    # if state is failed - we stop and fail creation
    # if state is queued - we continue polling in 2 minutes
    # if state is succeeded - we stop and succeed creation
    if 'FAILED' == response['QueryExecution']['Status']['State']:
        logger.error("Query failed")
        raise ValueError("Query failed")

    if 'SUCCEEDED' == response['QueryExecution']['Status']['State']:
        logger.error("Query SUCCEEDED")
        return True

    if 'QUEUED' == response['QueryExecution']['Status']['State']:
        logger.error("Query QUEUED")
        return False

    # Return a resource id or True to indicate that creation is complete. if True is returned an id
    # will be generated
    # Return false to indicate that creation is not complete and we need to poll again
    return False

def handler(event, context):
    helper(event, context)

用于视图创建/更新/删除的Athena查询作为环境参数传递给 Lambda。 CloudFormation模板中,我们必须定义调用提到的Python代码并创建/更新/删除Athena视图的 Lambda。 例如

  AthenaCommonViewLambda:
    Type: 'AWS::Lambda::Function'
    DependsOn: [CreateAthenaViewLayer, CreateAthenaViewLambdaRole]
    Properties:
      Environment:
        Variables:
          athena_workgroup: !Ref AudienceAthenaWorkgroup
          database:
            Ref: DatabaseName
          query_create: !Sub >-
            CREATE OR REPLACE VIEW ${TableName}_view AS
            SELECT field1, field2, ...
            FROM ${DatabaseName}.${TableName}
          query_drop: !Sub DROP VIEW IF EXISTS ${TableName}_common_view
      Code:
        S3Bucket: !Ref SourceS3Bucket
        S3Key: createview.zip
      FunctionName: !Sub '${AWS::StackName}_create_common_view'
      Handler: createview.handler
      MemorySize: 128
      Role: !GetAtt CreateAthenaViewLambdaRole.Arn
      Runtime: python3.8
      Timeout: 60
      Layers:
        - !Ref CreateAthenaViewLayer

  AthenaCommonView:
    Type: 'Custom::AthenaCommonView'
    Properties:
      ServiceToken: !GetAtt AthenaCommonViewLambda.Arn

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM