Импорт файла JSON в DynamoDB
Я новичок в AWS, DynamoDB и Python, поэтому я борюсь с выполнением этой задачи. Я использую Amazon Transcribe с видео и получаю вывод в виде файла JSON. Затем я хочу сохранить эти данные в DynamoDB.
В настоящее время я использую функцию Lambda для автоматизации процесса, когда файл JSON выгружается в корзину S3. Всякий раз, когда происходит процесс, я получаю сообщение об ошибке в CloudWatch:
[ERROR] ClientError: An error occurred (ValidationException) when calling the PutItem operation: One or more parameter values were invalid: Missing the key type in the item
Traceback (most recent call last):
File "/var/task/lambda_function.py", line 79, in lambda_handler
table.put_item(Item=jsonDict) # Adds string of JSON file into the database
File "/var/runtime/boto3/resources/factory.py", line 520, in do_action
response = action(self, *args, **kwargs)
File "/var/runtime/boto3/resources/action.py", line 83, in __call__
response = getattr(parent.meta.client, operation_name)(**params)
File "/var/runtime/botocore/client.py", line 320, in _api_call
return self._make_api_call(operation_name, kwargs)
File "/var/runtime/botocore/client.py", line 623, in _make_api_call
raise error_class(parsed_response, operation_name)
Вот мой код Python, который пытается создать таблицу DynamoDB и затем проанализировать файл JSON:
import boto3 # import to pull AWS SDK for Python
import json # import API for Python to work with JSON files
import time # import time fucntions
s3_client = boto3.client('s3') # creates low-level service client to AWS S3
dynamodb = boto3.resource('dynamodb') # creates resource client to AWS DynamoDB
# When a .JSON file is added into the linked S3 bucket, another JSON file is created which contains
# the information about the S3 Bucket and the name of the file that was added to the bucket
def lambda_handler(event, context):
print(str(event))
# Print the JSON file created by S3 into CloudWatch Logs when an item is added into the bucket
bucket = event['Records'][0]['s3']['bucket']['name']
# Here the name of the S3 bucket is assigned to the variable 'bucket'
# by grabbing the name from the JSON file created
json_file_name = event['Records'][0]['s3']['object']['key']
# Here the name of the file itself is assigned to the varibale 'json_file_name'
# again by grabbing the name of the added file from the JSON file
tname = json_file_name[:-5]
# Defines the name of the table being added to dynamodb by using the name of S3 JSON file
# *Use of [:.5] will strip the last five characters off the end of the file name
print(tname)
# Prints the name of the table into CloudWatch Logs
json_object = s3_client.get_object(Bucket=bucket,Key=json_file_name)
# The json_object variable is assigned the values of the 'bucket' and the 'json_file_name'
# This uses the boto3 client service and the rest of the script will reference the specified
# S3 bucket and the JSON file that was added to the bucket
jsonFileReader = json_object['Body'].read()
# The jsonFileReader variable takes this object and read the body of JSON file
jsonDict = json.loads(jsonFileReader)
# Using the json.loads function, the arrays of the JSON file are converted into a string
table = dynamodb.create_table(
TableName=tname, ## Define table name from name of JSON file in S3
KeySchema=[
{
'AttributeName': 'type', #Primary Key
'KeyType': 'HASH' #Partition Key
}
],
AttributeDefinitions=[
{
'AttributeName': 'type',
'AttributeType': 'S' #AttributeType N meas 'Number'
}
],
ProvisionedThroughput=
{
'ReadCapacityUnits': 10000,
'WriteCapacityUnits': 10000
}
)
# table.meta.client.get_waiter('table_exists').wait(TableName=tname)
print(str(jsonDict))
table.meta.client.get_waiter('table_exists').wait(TableName=tname)
table = dynamodb.Table(tname) # Specifies table to be used
table.put_item(Item=jsonDict) # Adds string of JSON file into the database
Я не очень разбираюсь в разборе вложенных файлов JSON и не имею опыта работы с DynamoDB. Любая помощь, чтобы получить эту функцию была бы чрезвычайно полезна!
Вот файл JSON, который я пытаюсь проанализировать:
{
"results": {
"items": [{
"start_time": "15.6",
"end_time": "15.95",
"alternatives": [{
"confidence": "0.6502",
"content": "Please"
}],
"type": "pronunciation"
}, {
"alternatives": [{
"confidence": null,
"content": "."
}],
"type": "punctuation"
}, {
"start_time": "15.95",
"end_time": "16.2",
"alternatives": [{
"confidence": "0.9987",
"content": "And"
}],
"type": "pronunciation"
}, {
"start_time": "16.21",
"end_time": "16.81",
"alternatives": [{
"confidence": "0.9555",
"content": "bottles"
}],
"type": "pronunciation"
}, {
"start_time": "16.81",
"end_time": "17.01",
"alternatives": [{
"confidence": "0.7179",
"content": "of"
}],
"type": "pronunciation"
}, {
"start_time": "17.27",
"end_time": "17.36",
"alternatives": [{
"confidence": "0.6274",
"content": "rum"
}],
"type": "pronunciation"
}, {
"start_time": "18.12",
"end_time": "18.5",
"alternatives": [{
"confidence": "0.9977",
"content": "with"
}],
"type": "pronunciation"
}, {
"start_time": "18.5",
"end_time": "19.1",
"alternatives": [{
"confidence": "0.3689",
"content": "tattoos"
}],
"type": "pronunciation"
}, {
"start_time": "19.11",
"end_time": "19.59",
"alternatives": [{
"confidence": "1.0000",
"content": "like"
}],
"type": "pronunciation"
}, {
"start_time": "19.59",
"end_time": "20.22",
"alternatives": [{
"confidence": "0.9920",
"content": "getting"
}],
"type": "pronunciation"
}, {
"start_time": "20.22",
"end_time": "20.42",
"alternatives": [{
"confidence": "0.5659",
"content": "and"
}],
"type": "pronunciation"
}, {
"start_time": "20.43",
"end_time": "20.97",
"alternatives": [{
"confidence": "0.6694",
"content": "juggle"
}],
"type": "pronunciation"
}, {
"start_time": "21.2",
"end_time": "21.95",
"alternatives": [{
"confidence": "0.8893",
"content": "lashes"
}],
"type": "pronunciation"
}, {
"alternatives": [{
"confidence": null,
"content": "."
}],
"type": "punctuation"
}, {
"start_time": "21.95",
"end_time": "22.19",
"alternatives": [{
"confidence": "1.0000",
"content": "And"
}]
}]
}
}
Другая проблема, с которой я столкнулся, заключается в том, как бороться с пунктуацией, поскольку AWS Transcribe не назначает отметки времени этим элементам.
Любая помощь приветствуется, спасибо!
0 ответов
Важной вещью в базе данных является ключ, он должен быть уникальным для вашей строки данных. В вашем случае [Вариант 1], если вы намереваетесь поместить каждый файл json в отдельное имя таблицы (tname), вам нужно будет предоставить набор уникальных значений, который в этом случае выглядит как start_time. В качестве альтернативы [Вариант 2] вы можете иметь одну и ту же таблицу со всеми текущими и будущими данными, помещенными здесь, и сохранить ключ как tname assummin, это будет уникально для данных.
Опция 1
Замените "AttributeName": "type" в KeySchema и AttributeDefinitions на "AttributeName": "start_time"
##This is a way to batch write
with table.batch_writer() as batch:
for item in jsonDict["results"]["items"]:
batch.put_item(Item=item)
Вариант 2
Здесь вы не должны создавать таблицы каждый раз. Просто создайте его один раз, а затем каждая запись будет добавлена в базу данных. В приведенном ниже коде имя таблицы "commonTable"
Замените "AttributeName": "type" в KeySchema и AttributeDefinitions на"AttributeName": "tname"
table.meta.client.get_waiter('table_exists').wait(TableName="commonTable")
table = dynamodb.Table(tname) # Specifies table to be used
jsonDict['tname'] = tname # this is also the key name 'tname'
table.put_item(Item=jsonDict)