Создайте AWS Athena view программно - PullRequest
2 голосов
/ 24 мая 2019

Можно ли создавать представления в 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" }
}

Альтернативой, которую я бы с удовольствием использовал, является CLI AWS, однако aws athena [option] не предоставляет для этого опции.

Я пробовал:

  • create-named-query , который я не смог заставить работать с оператором, таким как CREATE OR REPLACE VIEW поскольку это не похоже на предполагаемый вариант использования этой команды.
  • start-query-execute , который запрашивает выходное местоположение, что предполагает, что это предназначено для запроса данныхи вывод результатов, а не внесение измененийЦИИ.Похоже, что он также связан с stop-query-execute .

Ответы [ 3 ]

3 голосов
/ 28 мая 2019

Создание представлений программно в Афине не задокументировано и не поддерживается, но возможно.Что происходит за кулисами, когда вы создаете представление с использованием StartQueryExecution, так это то, что Athena позволяет Presto создавать представление, а затем извлекает внутреннее представление Presto и помещает его в каталог Glue.

Проблема устаревания обычно возникает из столбцов.в метаданных Presto и в метаданных Glue, которые не синхронизированы.Представление Athena действительно содержит три описания представления: представление SQL, столбцы и их типы в формате Glue, а также столбцы и типы в формате Presto.Если какой-либо из них выйдет из синхронизации, вы получите «… устарело; оно должно быть воссоздано».ошибка.

Это требования к таблице Glue для работы в качестве представления Athena:

  • TableType должно быть VIRTUAL_VIEW
  • Parameters mustсодержать presto_view: true
  • TableInput.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 в кодировке 64, которая содержит представление SQL, столбцы и их типы, а также некоторые метаданные каталога (см. Ниже)
  • Добавляет суффикс */ (обратите внимание на начальный пробел)

JSON, который описывает представление, выглядит следующим образом:

  • A catalog свойство, которое должно иметь значение awsdatacatalog.
  • A schema свойство, котороедолжно быть именем базы данных, в которой создается представление (т. е. оно должно соответствовать свойству DatabaseName окружающей структуры Glue.
  • Список столбцов, каждый из которых содержит name и type
  • Свойство originalSql с фактическим 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"
}

Одно предостережение: типы столбцов почти, но не совсем совпадают с именами.в клее.Если Athena / Glue будет иметь string, значение в этом JSON должно быть varchar.Если Athena / Glue использует array<string>, значение в этом JSON должно быть array(string), а struct<foo:int> становится struct(foo int).

Это довольно грязно, и для того, чтобы собрать все вместе, нужно немного потрудиться и протестировать,Самый простой способ заставить его работать - это создать несколько представлений и расшифровать, выполнив инструкции, приведенные выше, чтобы посмотреть, как они выглядят, а затем попробовать сделать это самостоятельно.

1 голос
/ 25 мая 2019

Как вы и предполагали, определенно возможно программно создать представление Athena через CLI AWS, используя start-query-execution.Как вы указали, для этого требуется указать местоположение S3 для результатов, даже если вам не нужно проверять файл (по какой-то причине Афина поместит пустой текстовый файл в это местоположение).

Вот пример:

$ 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"
}

Вы можете не допустить, чтобы клиент задал корзину с помощью c , создав рабочую группу и указав ее местоположение.

Вы можете проверить,Вы просматриваете создание успешно с помощью команды 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"
    }
}

0 голосов
/ 29 мая 2019

Чтобы добавить к ответам JD D и Theo, работая с их решениями, мы выяснили, как вызывать AWS Cli через terraform следующим образом:

resource "null_resource" "athena_view" {

  provisioner "local-exec" {
    command = <<EOF
aws sts assume-role \
  --output json \
  --region my_region \
  --role-arn arn:aws:iam::${var.account_number}:role/my_role \
  --role-session-name create_my_view > /tmp/credentials.json

export AWS_SESSION_TOKEN=$(jq -r '.Credentials.SessionToken' /tmp/credentials.json)
export AWS_ACCESS_KEY_ID=$(jq -r '.Credentials.AccessKeyId' /tmp/credentials.json)
export AWS_SECRET_ACCESS_KEY=$(jq -r '.Credentials.SecretAccessKey' /tmp/credentials.json)

aws athena start-query-execution \
  --output json \
  --region my_region \
  --query-string "CREATE OR REPLACE VIEW my_view AS SELECT * FROM my_table \
  --query-execution-context "Database=${var.database_name}" \
  --result-configuration "OutputLocation=s3://${aws_s3_bucket.my-bucket.bucket}"
EOF
  }
}

Мы используем null_resource ... для запуска провайдеров, которые не связаны напрямую с конкретным ресурсом .

Результат aws sts assume-role выводится как JSON в /tmp/credentials.json.

jq используется для анализа необходимых полей из вывода aws sts accept-role .

aws athena start-query-execute затем может выполняться под ролью, определенной переменными среды, определенными.

Вместо --result-configuration "OutputLocation=s3://.... можно указать --work-group, ОБРАТИТЕ ВНИМАНИЕ, что это отдельный флаг для start-query-execution, а не часть строки --result-configuration.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...