Разбор Json - от sql (Аврора) до aws лямбда
Я не могу разобрать JSON, как это от SQL до лямбда. Скажем ниже, моя хранимая процедура, которая вызывает лямбда-API.
CALL mysql.lambda_async('arn:aws:lambda:us-east-1:<account_id>:function:<sample_name>', <---- this should be your lambda function ARN
CONCAT('{ "message_id" : "', 'test.txt',
'", "transaction_json" : "', '{"glossary": {
"title": "example glossary",
"GlossDiv": {
"title": "S",
"GlossList": {
"GlossEntry": {
"ID": "SGML",
"SortAs": "SGML",
"GlossTerm": "Standard Generalized Markup Language",
"Acronym": "SGML",
"Abbrev": "ISO 8879:1986",
"GlossDef": {
"para": "A meta-markup language, used to create markup languages such as DocBook.",
"GlossSeeAlso": ["GML", "XML"]
},
"GlossSee": "markup"
}
}
}}}',
'", "s3_bucket" : "', 'br-gtosbx-gtps-data-useast-1-s3',
'"}'));
Теперь это вызовет лямбда-функцию, написанную на python 3.6.
def s3_publish_message(event, context):
import boto3
import botocore
import json
s3 = boto3.client('s3')
s3_bucket = event['s3_bucket']
#transaction_json = event['transaction_json']
try:
event_str = str(json.dumps(event['transaction_json'])).encode("utf-8")
print("s3 Load Completed")
except Exception as err:
print("Could not convert event to string for storage. Threw exception: {}".format(err))
message_id = event['message_id']
s3.put_object(ACL='private',
Body=event_str,
Bucket=s3_bucket,
StorageClass='STANDARD',
Tagging='test',
Key=message_id)
Когда я запускаю хранимую процедуру в MySQL, я получаю ошибку ниже.
Error Code: 1873. Lambda API returned error: Invalid Request Content. Could not parse request body into json: Unexpected character ('g' (code 103)): was expecting comma to separate Object entries at [Source: [B@616b0a0f; line: 1, column: 55]
Есть ли способ я могу справиться с этим или мы должны отправить JSON без (")
1 ответ
Вы не можете встроить объект JSON в строку JSON таким образом. Вы можете сделать это, но не так, как вы это делаете. Это просто не работает таким образом.
Но вам также не нужно это делать.
JSON - это формат сериализации объектов - он принимает логические объекты и представляет их в символьной строке. Он обычно используется между несопоставимыми системами для обеспечения возможности переноса объекта через среду, например HTTP, которая не имеет внутренней концепции "объекта" с парами ключ / значение, массивами и строками.
Весь ваш второй аргумент mysql.lambda_async()
это JSON. Вы говорите, что transaction_json
это строка, а не просто вложенный объект.
"transaction_json" : "{"glossary": ...
Это неправильно, потому что если это строка, то она неправильно закодирована как строка JSON, потому что строки JSON не могут содержать неэкранированные "
а также некоторые другие персонажи.
Но в этом нет необходимости. Просто удалите внешние кавычки.
Примите все, что вы передаете, второму аргументу mysql.lambda_async()
и вставьте его в валидатор, например http://jsonlint.com/ и вы увидите, что это действительно недопустимый JSON.
Удалить "
окружая значение транзакции_json, и объект будет действительным.
'", "transaction_json" : "', '{"glossary # old
'", "transaction_json" : {"glossary # new
...а также...
'", "s3_bucket" : "', 'br-gtosbx-gtps-data-useast-1-s3', # old
', "s3_bucket" : "', 'br-gtosbx-gtps-data-useast-1-s3', # new
Но также, вы технически неправильно назвали это поле. Это не транзакция JSON. Это просто объект транзакции. Внешний контейнер - JSON, внутреннее значение - нет.
С удаленными внешними кавычками, event_str = str(json.dumps(event['transaction_json'])).encode("utf-8")
не нужно, потому что event['transaction_json']
это уже объект - Lambda будет десериализовать всю структуру события.