AWS Athena: именованные запросы boto3 не создают соответствующие таблицы - PullRequest
0 голосов
/ 06 ноября 2019

У меня есть следующий boto3 черновой сценарий

#!/usr/bin/env python3
import boto3

client = boto3.client('athena')

BUCKETS='buckets.txt'
DATABASE='some_db'
QUERY_STR="""CREATE EXTERNAL TABLE IF NOT EXISTS some_db.{}(
         BucketOwner STRING,
         Bucket STRING,
         RequestDateTime STRING,
         RemoteIP STRING,
         Requester STRING,
         RequestID STRING,
         Operation STRING,
         Key STRING,
         RequestURI_operation STRING,
         RequestURI_key STRING,
         RequestURI_httpProtoversion STRING,
         HTTPstatus STRING,
         ErrorCode STRING,
         BytesSent BIGINT,
         ObjectSize BIGINT,
         TotalTime STRING,
         TurnAroundTime STRING,
         Referrer STRING,
         UserAgent STRING,
         VersionId STRING,
         HostId STRING,
         SigV STRING,
         CipherSuite STRING,
         AuthType STRING,
         EndPoint STRING,
         TLSVersion STRING
) 
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
WITH SERDEPROPERTIES (
         'serialization.format' = '1', 'input.regex' = '([^ ]*) ([^ ]*) \\[(.*?)\\] ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) \\\"([^ ]*) ([^ ]*) (- |[^ ]*)\\\" (-|[0-9]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) (\"[^\"]*\") ([^ ]*)(?: ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*))?.*$' )
LOCATION 's3://my-bucket/{}'"""

with open(BUCKETS, 'r') as f:
    lines = f.readlines()


for line in lines:
    query_string = QUERY_STR.format(line, line)
    response = client.create_named_query(
        Name=line,
        Database=DATABASE,
        QueryString=QUERY_STR
    )
    print(response)

При выполнении все ответы возвращаются с кодом состояния 200.

Почему я не могу увидеть соответствующийтаблицы, которые должны были быть созданы?

Разве я не смогу (по крайней мере) увидеть где-то эти хранимые запросы?

update1 : я сейчас пытаюсь на самом делеСоздайте таблицы с помощью вышеуказанных запросов следующим образом:

for line in lines:
    query_string = QUERY_STR.format(DATABASE, line[:-1].replace('-', '_'), line[:-1])
    try:
        response1 = client.start_query_execution(
            QueryString=query_string,
            WorkGroup=WORKGROUP,
            QueryExecutionContext={
                'Database': DATABASE
            },
            ResultConfiguration={
                'OutputLocation': OUTPUT_BUCKET,
            },
        )
        query_execution_id = response1['ResponseMetadata']['RequestId']
        print(query_execution_id)
    except Exception as e1:
        print(query_string)
        raise(e1)

Еще раз, скрипт выводит некоторые идентификаторы запросов (похоже, что ошибки не происходит), тем не менее, таблица не создается.

Я также последовал совету @John Rotenstein и инициализировал моего boto3 клиента следующим образом:

client = boto3.client('athena', region_name='us-east-1')

Ответы [ 2 ]

0 голосов
/ 07 ноября 2019

Чтобы воспроизвести вашу ситуацию, я сделал следующее:

  • В консоли Athena я запустил:
CREATE DATABASE foo
  • В консоли Athena:Я выбрал foo в раскрывающемся списке База данных
  • Для простоты я запустил этот код Python:
import boto3

athena_client = boto3.client('athena', region_name='ap-southeast-2') # Change as necessary

QUERY_STR="""
CREATE EXTERNAL TABLE IF NOT EXISTS foo.bar(id INT) 
LOCATION 's3://my-bucket/input-files/'
"""

response = athena_client.start_query_execution(
    QueryString=QUERY_STR,
    QueryExecutionContext={'Database': 'foo'},
    ResultConfiguration={'OutputLocation': 's3://my-bucket/athena-out/'}
)
  • Затем я пошел к консоли Athena, сделал обновление и подтвердил, что таблица bar была создана

Предложение: Попробуйте выше, чтобы подтвердить, что она работает и для вас!

Затем я запустил ваш код, используя start_query_execution версию вашего кода (показанную во втором блоке кода). Мне пришлось внести некоторые изменения:

  • У меня не было файла buckets.txt, поэтому я просто предоставил список имен
  • Ваш код не отображает содержимоеOUTPUT_BUCKET, поэтому я использовал s3://my-bucket/athena-output/ (соответствует ли формат, который вы использовал?)
  • Ваш код использует QUERY_STR.format(DATABASE..., но в * 1040 не было {}* где имя базы данных будет вставлено, поэтому я удалил DATABASE в качестве входных данных для переменной формата
  • Я не предоставил значение для WORKGROUP

Все работало нормально , создавая несколько таблиц.

Итак, проверьте указанные выше маркеры, чтобы увидеть, не вызвало ли это проблемы для вас (например, заменить имя базы данных вformat() заявление).

0 голосов
/ 06 ноября 2019

Прежде всего, response просто говорит вам, что ваш запрос был успешно отправлен. Метод create_named_query() создает фрагмент вашего запроса, который затем можно просмотреть / открыть в консоли AWS Athena на вкладке Сохраненные запросы .

enter image description here

Мне кажется, что вы хотите создать таблицу, используя boto3. В этом случае вам необходимо использовать метод start_query_execution().

Запускает операторы SQL-запросов, содержащиеся в Запросе. Требует, чтобы у вас был доступ к рабочей группе, в которой выполнялся запрос.

Наличие ответа 200 из start_query_execution не гарантирует успешного выполнения вашего запроса. Как я понимаю, этот метод выполняет несколько простых проверок перед выполнением для проверки синтаксиса запроса. Однако есть и другие вещи, которые могут привести к сбою во время выполнения запроса. Например, если вы пытаетесь создать таблицу в несуществующей базе данных, или если вы пытаетесь создать определение таблицы в базе данных, к которой у вас нет доступа.

Вот пример, когдаЯ использовал строку запроса, отформатированную с некоторым произвольным именем для таблицы.

enter image description here

Я получил ответ 200 и получил некоторое значение в response1['ResponseMetadata']['RequestId']. Однако, поскольку у меня нет some_db в каталоге AWS Glue, этот запрос не был выполнен во время выполнения, поэтому таблица не была создана.

Вот как можно отслеживать выполнение запроса в boto3

import time

response1 = client.start_query_execution(
    QueryString=query_string,
    WorkGroup=WORKGROUP,
    QueryExecutionContext={
        'Database': DATABASE
    },
    ResultConfiguration={
        'OutputLocation': OUTPUT_BUCKET,
    },
)
query_execution_id = response1['ResponseMetadata']['RequestId']

while True:
    time.sleep(1)
    response_2 = client.get_query_execution(
        QueryExecutionId=query_execution_id
    )
    query_status = response_2['QueryExecution']['Status']
    print(query_status)
    if query_status not in ["QUEUED", "RUNNING", "CANCELLED"]:
        break
...