Свернуть результаты низкоуровневого интерфейса DynamoDB в исходный формат json - PullRequest
0 голосов
/ 08 марта 2020

Недавно мне пришлось переключиться с высокоуровневого AWS DynamoDB python boto3 API на низкоуровневый, чтобы я мог общаться с AWS DAX кеш-машиной. Удивительно, но самой большой проблемой при использовании низкоуровневого API был формат, который он использует для представления результата запроса. Он содержит не только данные, но также и индикаторы типов данных, которые ставятся в качестве ключей dict ... Я придумал короткую функцию для решения этой проблемы. Я хотел бы поделиться этим здесь, возможно, кто-то еще может иметь подобную проблему и считает это полезным. Также я хотел бы спросить вас, ребята, могли бы вы предложить лучший способ справиться с таким преобразованием.

def fold(z):
    """ Fold DynamoDB low level interface query result into its original json format """

    if type(z) == list:
        return [fold(x[y]) if (y := next(iter(x))) in {"M", "L"} else x[y] for x in z]

    elif type(z) == dict:
        return {x: fold(z[x][y]) if (y := next(iter(z[x]))) in {"M", "L"} else z[x][y] for x in z}

Вот пример ввода ...

{'formats': {'M': {'command_output': {'M': {'show clock': {'S': 'Output...'},
     'show version': {'S': 'Output...'},
     'show ip interfaces brief': {'S': 'Output...'}}}}},
 'device_type': {'M': {'cisco_asa_mc': {'L': [{'S': 'vf1fw1'},
     {'S': 'vf2fw1'},
     {'M': {'t1': {'S': 'to1'}, 't2': {'S': 'to2'}, 't3': {'S': 'to3'}}}]},
   'cisco_switch': {'L': [{'S': 'aklas1'},
     {'S': 'aklds1'},
     {'S': 'ams2as1'},
     {'S': 'asdas1'},
     {'L': [{'S': 'test1'}, {'S': 'test2'}]}]}}},
 'name': {'S': 'labwr1'},
 'type': {'S': 'cisco_router'},
 'timestamp': {'S': '2020-03-07 14:21:11 EDT'}}

и пример вывода. ..

{'formats': {'command_output': {'show clock': 'Output...',
   'show version': 'Output...',
   'show ip interfaces brief': 'Output...'}},
 'device_type': {'cisco_asa_mc': ['vf1fw1',
   'vf2fw1',
   {'t1': 'to1', 't2': 'to2', 't3': 'to3'}],
  'cisco_switch': ['aklas1',
   'aklds1',
   'ams2as1',
   'asdas1',
   ['test1', 'test2']]},
 'name': 'labwr1',
 'type': 'cisco_router',
 'timestamp': '2020-03-07 14:21:11 EDT'}

1 Ответ

0 голосов
/ 23 марта 2020

Вместо того, чтобы переходить к собственному решению, рассмотрите возможность использования boto3 TypeDeserializer:

from boto3.dynamodb.types import TypeDeserializer

serde = TypeDeserializer()
out = {k: serde.deserialize(v) for k, v in your_input.items()}

В этом же модуле вы также найдете TypeSerializer до go другой путь.

...