AWS DynamoDB提供的键元素与架构不匹配

2024-06-01 01:35:58 发布

您现在位置:Python中文网/ 问答频道 /正文

我在AWS Cloud9上创建了一个Python程序,该程序将列表写入DynamoDB,并提示用户访问信息。当我运行程序时,我可以输入主题和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
    }
}

Tags: thetoinfonavigatortitletableboto3dynamodb
1条回答
网友
1楼 · 发布于 2024-06-01 01:35:58

就像注释中提到的@hoangdv一样,您使用的Key参数是不正确的。您必须使用散列键才能这样做(Key={'CourseID': '3'},例如)。如果要基于SubjectCatalogNbr获取行,则必须扫描表,然后查找与要查找的键匹配的结果。下面是一个代码示例,可用于基于SubjectCatalogNbr获取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作为Hask键,使用CatalogNbr作为排序键。在这种情况下,您只需确保此组合是唯一的

相关问题 更多 >