Python как анализировать вывод Amazon RDS Data Service

Я изо всех сил пытаюсь проанализировать вывод действия ExecuteStatement с помощью службы данных Amazon RDS https://docs.aws.amazon.com/rdsdataservice/latest/APIReference/API_ExecuteStatement.html

Документация очень плохая, и я не могу найти каких-либо значимых примеров.

Я использую Aurora MySql DB

Результат возвращается вот так. Этот пример представляет собой 2 строки данных, возвращаемых оператором SELECT, я заменил фактические данные словом "данные".

 {'ResponseMetadata': {'RequestId': '955a6aee-5bad-4f87-a455-b83a10a8a31b', 'HTTPStatusCode': 200, 'HTTPHeaders': {'x-amzn-requestid': '955a6aee-5bad-4f87-a455-b83a10a8a31b', 'content-type': 'application/json', 'content-length': '809', 'date': 'Tue, 02 Jun 2020 05:39:22 GMT'}, 'RetryAttempts': 0}, 'numberOfRecordsUpdated': 0, 'records': [[{'stringValue': 'data'}, {'longValue': data}, {'stringValue': 'data'}, {'stringValue': 'data'}, {'stringValue': ''}, {'stringValue': 'data'}, {'stringValue': 'data'}, {'stringValue': 'data'}, {'stringValue': 'data'}, {'stringValue': 'data'}, {'stringValue': 'data'}, {'stringValue': 'data'}, {'stringValue': 'data'}], [{'stringValue': 'data'}, {'longValue': data}, {'stringValue': 'data'}, {'stringValue': 'data'}, {'stringValue': ''}, {'stringValue': 'data'}, {'stringValue': 'data'}, {'stringValue': 'data'}, {'stringValue': 'data'}, {'stringValue': 'data'}, {'stringValue': 'data'}, {'stringValue': 'data'}, {'stringValue': 'data'}]]}

На самом деле мне нужно извлечь только эти поля данных, поэтому я могу использовать их для оператора INSERT в другой таблице.

Согласно документации исходный ответ - это тип данных словаря, поэтому я получаю здесь 3 ключа: "ResponseMetadata", "numberOfRecordsUpdated" и "records". Согласно документации "записи" - это Тип: Массив массивов объектов поля, и вот где я застрял. Как я могу извлечь объекты поля из массива массивов внутри словаря?

3 ответа

Решение

Есть много способов, но достаточно простого вложенного цикла for в python:

data_values = []

for record in result['records']:
    print()
    row_data = []
    for data_dict in record:
        #print(data_dict)
        for data_type, data_value in data_dict.items():
            print(data_type, data_value)
            row_data.append(data_value)

    data_values.append(row_data)

print(data_values)  

Код может стать хорошей основой для изменений в соответствии с вашими потребностями. Это дает следующее:

stringValue data
longValue data
stringValue data
stringValue data
stringValue 
stringValue data
stringValue data
stringValue data
stringValue data
stringValue data
stringValue data
stringValue data
stringValue data

stringValue data
longValue data
stringValue data
stringValue data
stringValue 
stringValue data
stringValue data
stringValue data
stringValue data
stringValue data
stringValue data
stringValue data
stringValue data

А также data_values:

[['data', 'data', 'data', 'data', '', 'data', 'data', 'data', 'data', 'data', 'data', 'data', 'data'], ['data', 'data', 'data', 'data', '', 'data', 'data', 'data', 'data', 'data', 'data', 'data', 'data']]

Вы получаете это

response = 
{'ResponseMetadata': {'HTTPHeaders': {'content-length': '809',
                                      'content-type': 'application/json',
                                      'date': 'Tue, 02 Jun 2020 05:39:22 GMT',
                                      'x-amzn-requestid': '955a6aee-5bad-4f87-a455-b83a10a8a31b'},
                      'HTTPStatusCode': 200,
                      'RequestId': '955a6aee-5bad-4f87-a455-b83a10a8a31b',
                      'RetryAttempts': 0},
 'numberOfRecordsUpdated': 0,
 'records': [[{'stringValue': 'data'},
              {'longValue': 'data'},
              {'stringValue': 'data'},
              {'stringValue': 'data'},
              {'stringValue': ''},
              {'stringValue': 'data'},
              {'stringValue': 'data'},
              {'stringValue': 'data'},
              {'stringValue': 'data'},
              {'stringValue': 'data'},
              {'stringValue': 'data'},
              {'stringValue': 'data'},
              {'stringValue': 'data'}],
             [{'stringValue': 'data'},
              {'longValue': 'data'},
              {'stringValue': 'data'},
              {'stringValue': 'data'},
              {'stringValue': ''},
              {'stringValue': 'data'},
              {'stringValue': 'data'},
              {'stringValue': 'data'},
              {'stringValue': 'data'},
              {'stringValue': 'data'},
              {'stringValue': 'data'},
              {'stringValue': 'data'},
              {'stringValue': 'data'}]]}

Вы можете читать свои строки, повторяя response['records']

data_fields = []
for row in response['records']:
    for field in row:
        if field['stringValue']:
           print(field)
           data_fields.append(field)
        elif field['longValue']:
           print(field)
           data_fields.append(field)

Рассмотрите возможность использования словарного курсора, напрямую обращаясь к базе данных с помощью конфигурации подключения mysql, например, чтобы вы не видели метаданные запроса aws.

import mysql.connector

cnx = mysql.connector.connect(user='username', password='password',
                              host='aws rds mysql host',
                              database='database_name')
cnx.close()

Вы можете увидеть детали подключения mysql из консоли AWS.

https://dev.mysql.com/doc/connector-python/en/connector-python-example-connecting.html

В качестве альтернативы, если вы хотите обрабатывать свои данные в стиле «диктофона», например, если вы используете анализ модели pydantic, вы можете сделать что-то вроде этого

ПРИМЕЧАНИЕ: вам нужно добавить

      includeResultMetadata=True

вexecute_statementзватьcolumnMetadataприсутствовать

      columns_metadata = result.get('columnMetadata')

object_list = []

for record in result.get('records'):
    row_dict = {}
    for i in range(len(columns_metadata)):
        column = columns_metadata[i].get("name")
        data_dict = record[i]
        for data_type, data_value in data_dict.items():
            if data_type == "isNull" and data_value is True:
                row_dict[column] = None
            else:
                row_dict[column] = data_value

    object_list.append(row_dict)

Это даст вам список всех записей в следующем формате:

      object_list = [
    {
        "col1": "obj1val1",
        "col2": "obj1val2",
        "col3": "obj1val3",
    },
    {
        "col1": "obj2val1",
        "col2": "obj2val2",
        "col3": "obj2val3",
    }
]

NB: Вероятно, это можно оптимизировать для повышения производительности (в настоящее время написано для удобства чтения).

Другие вопросы по тегам