Изменить сообщение JSON при чтении из AWS SNS с помощью AWS Lambda - PullRequest
0 голосов
/ 13 февраля 2019

У меня есть вышестоящее приложение, отправляющее следующее сообщение JSON в тему SNS.Мы используем лямбда-функцию AWS для сохранения этого объекта JSON в S3:

{
"processResult": {
    "processName": "XYZ",
    "stageResults": {
        "Read Files": {
            "status": "PROCESSED",
            "error": "",
            "timeTaken": 26064469473
        },
        "Convert Files": {
            "status": "PROCESSED",
            "error": "",
            "timeTaken": 97968896
        }
    },
    "processMetrics": {
        "filesProcessed": 1157,
        "filesWithExceptionCount": 1,
        "timeTaken": "367.460031s",
        "metricsCalcTime": "6.061847s",
        "totalTimeTaken": "373.521878s"
    },
    "succeeded": true
  }
}

Если вы наблюдаете в рамках STRUCT "stageResults", у меня есть атрибуты с пробелами, такие как "Чтение файлов" и "Преобразование файлов" иКогда я пытаюсь прочитать этот JSON из S3 с помощью AWS Athena (AWS Glue Crawler), я получаю следующую ошибку:

    HIVE_METASTORE_ERROR: com.facebook.presto.spi.PrestoException: Error: : expected at the position 51 of 'struct<....
......but ' ' is found. (Service: null; Status Code: 0; Error Code: null; Request ID: null)

Но когда я вручную редактирую сообщение JSON, изменяя "stageResults" STRUCT like "Read_Files "и" Convert_Files ", я смог прочитать и запросить JSON с помощью таблиц AWS Athena.

Ниже приведен фрагмент кода из AWS Lambda, который запускается по теме SNS, читает сообщение JSON и сохраняет его вS3:

import json
import boto3
import random
import string

file_name = ''.join([random.choice(string.ascii_lowercase) for i in range(16)])

def lambda_handler(event, context):
    target_bucket = 'bucket-name'
    target_key = 'input=clientdata/'  + file_name + '.json'
    s3 = boto3.resource('s3')
    for record in event['Records']:
        payload = record["body"]
        data = json.loads(payload)
        print(data)
        print("copying JSON message...")
        s3.Object('target_bucket', 'target_key').put(
            Body=(bytes(json.dumps(data).encode('UTF-8')))
        )

Теперь я хочу узнать, как изменить это сообщение JSON, прежде чем сохранять его в S3 с помощью AWS Lambda.Любая помощь приветствуется.

1 Ответ

0 голосов
/ 14 февраля 2019

Если все, что вам нужно, это заменить каждый ключ, содержащий пробелы, на что-то подходящее для ваших нужд, это может сделать:

import re
wrong_keys = []
for key in data.keys():
    if key.strip().find(" ") != -1:
        wrong_keys.append(key)
for key in wrong_key:
  data[re.sub(r'[\W]+', '_',key)] = data.pop(key)
...