AWS DynamoDB - 提供的关键元素与架构不匹配
Posted
技术标签:
【中文标题】AWS DynamoDB - 提供的关键元素与架构不匹配【英文标题】:AWS DynamoDB - The provided key element does not match the schema 【发布时间】:2021-03-05 03:20:03 【问题描述】:我在 AWS Cloud9 上创建了一个 Python 程序,该程序将一个列表写入 DynamoDB 并提示用户访问信息。当我运行程序时,我可以输入 Subject 和 CatalogNbr,但是它会打印一个错误:
Enter the Subject:
SDEV
Enter the CatalogNbr:
450
The provided key element does not match the schema
表的键是第一个名为 CourseID 的值,它们被写成字符串:
['1','SDEV', '450', 'Advanced Programming', '3'],
我还将哈希键设置为字符串:
"AttributeDefinitions": [
"AttributeName": "CourseID",
"AttributeType": "S"
],
"KeySchema": [
"KeyType": "HASH",
"AttributeName": "CourseID"
],
我认为它似乎匹配。我已经尝试更改我定义的函数中的值并创建一个新表,但我仍然遇到同样的错误。 AWS 凭证都在 us-east-1 中。我不确定我需要解决什么问题。
这是我正在使用的代码:
import boto3
from boto3.dynamodb.conditions import Key
from botocore.exceptions import ClientError
import sys
# define DynamoDB variables
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('Courses')
# a list of 10 courses
allCourses = [
['1','SDEV', '450', 'Advanced Programming', '3'],
['2','SDEV', '325', 'Detecting Software Vulnerabilities', '3'],
['3','CMIS', '102', 'Media and Society', '3'],
['4','CMIS', '141', 'Indroductory Programming', '3'],
['5','CMIS', '242', 'Intermediate Programming', '3'],
['6','CMIS', '102', 'Introduction to Problem Solving and Algorithm Design', '3'],
['7','CMIS', '320', 'Relational Database Concepts and Applications', '3'],
['8','CHEM', '101', 'Intro to Chemistry', '3'],
['9','MATH', '200', 'Calculus 1', '3'],
['10','ECON', '101', 'Intro to Economics', '3']
]
# for each course in the "allCourses" list
for course in allCourses:
# assign values to variables
CourseID = course[0]
Subject = course[1]
CatalogNbr = course[2]
Title = course[3]
NumCredits = course[4]
# put item in table "Courses"
table.put_item(
Item=
'CourseID': CourseID,
'Subject': Subject,
'CatalogNbr': CatalogNbr,
'Title': Title,
'NumCredits': NumCredits
)
def check_class_info(Subject, CatalogNbr, dynamodb=None): # checks if class info exists
if not dynamodb:
dynamodb = boto3.resource('dynamodb')
try:
response = table.get_item(Key='Subject': Subject, 'CatalogNbr': CatalogNbr)
print(get_class_info(Subject, CatalogNbr, Title))
except ClientError as e:
print(e.response['Error']['Message'])
print("Course does not exist. Please try again")
print(end_navigator())
def get_class_info(Subject, CatalogNbr, Title, dynamodb=None): # gets class info from AllCourses
if not dynamodb:
dynamodb = boto3.resource('dynamodb')
try:
response = table.get_item(Key='Subject': Subject, 'CatalogNbr': CatalogNbr, 'Title': Title)
print("The title of ", Subject, " ", CatalogNbr, " is ", Title)
print(end_navigator())
except ClientError as e:
print(e.response['Error']['Message'])
print("Cannot retrieve class info. Please try again.")
print(end_navigator())
def end_navigator():
user_choice = input("Would you like to search for another title? Y or N\n")
if user_choice == "Y":
return navigator()
elif user_choice =="N":
sys.exit("Thank you for using the Course Title Navigator")
else:
print("Invalid entry. Please try again.")
return end_navigator()
def navigator():
print("Welcome to the Course Title Navigator\n") # User prompt
print("Enter the Subject: ")
Subject = str(input())
print("Enter the CatalogNbr: ")
CatalogNbr = str(input())
check_class_info(Subject, CatalogNbr)
print(get_class_info(Subject, CatalogNbr, Title))
print(end_navigator())
print(navigator())
这是桌子。
"Table":
"TableArn": "arn:aws:dynamodb:us-east-1:399520938535:table/Courses",
"AttributeDefinitions": [
"AttributeName": "CourseID",
"AttributeType": "S"
],
"ProvisionedThroughput":
"NumberOfDecreasesToday": 0,
"WriteCapacityUnits": 150,
"ReadCapacityUnits": 150
,
"TableSizeBytes": 753,
"TableName": "Courses",
"TableStatus": "ACTIVE",
"TableId": "6efba366-56d8-4ad6-86b2-8b14f161c94f",
"KeySchema": [
"KeyType": "HASH",
"AttributeName": "CourseID"
],
"ItemCount": 10,
"CreationDateTime": 1614907161.717
【问题讨论】:
能否添加您正在使用的代码或(部分代码)? 你能发布完整的表定义和你正在执行的查询吗?发生此错误通常是因为您没有提供正确的主键我是您的查询。enter the Subject and CatalogNbr
- 这是什么?
@samlima 我在帖子中添加了我的代码。
@SethGeoghegan 我使用定义表添加了表信息。这就是你要找的,对吗?
【参考方案1】:
就像评论中提到的@hoangdv一样,您使用的Key
参数不正确。您必须使用哈希键才能做到这一点(例如Key='CourseID': '3'
)。如果要根据Subject
和CatalogNbr
获取行,则必须扫描表,然后查找与您要查找的键匹配的结果。下面是一个代码示例,可用于根据Subject
和CatalogNbr
获取Title
:
def get_title(Subject, CatalogNbr):
response = table.scan()
row = next(item for item in response['Items'] if item['Subject'] == Subject and item['CatalogNbr'] == CatalogNbr)
title = row['Title']
print("The title of ", Subject, " ", CatalogNbr, " is ", title)
return title
另一种可能的解决方案是更改哈希键,即使用属性Subject
作为哈希键和CatalogNbr
作为排序键。在这种情况下,您只需确保此组合是唯一的。
【讨论】:
以上是关于AWS DynamoDB - 提供的关键元素与架构不匹配的主要内容,如果未能解决你的问题,请参考以下文章
DynamoDB / Scanamo:提供的关键元素与架构不匹配
DynamoDB 简单 UpdateItem 抛出“提供的关键元素与架构不匹配”ValidationException
我们可以通过 AWS SDK 使用 GSI 删除 DynamoDB 中的项目吗?
DynamoDB AmazonServiceException:提供的关键元素与架构不匹配