Hello World - 学生表 CRUD 操作

知识库
知识库文档
/tech-stacks/dynamodb/examples/Hello World - 学生表 CRUD 操作.md

文档

DynamoDB Hello World:学生表 CRUD 操作

目标

使用 Python (boto3) 操作 DynamoDB,完成建表、插入、查询、更新、删除等核心操作。

完整代码

# pip install boto3
import boto3
from decimal import Decimal
from datetime import datetime

# 使用本地 DynamoDB(开发环境)
dynamodb = boto3.resource(
    'dynamodb',
    endpoint_url='http://localhost:8000',
    region_name='us-east-1',
    aws_access_key_id='fake',
    aws_secret_access_key='fake'
)

# === 1. 创建表 ===
def create_table():
    table = dynamodb.create_table(
        TableName='Students',
        KeySchema=[
            {'AttributeName': 'student_id', 'KeyType': 'HASH'},  # 分区键
            {'AttributeName': 'enrolled_date', 'KeyType': 'RANGE'} # 排序键
        ],
        AttributeDefinitions=[
            {'AttributeName': 'student_id', 'AttributeType': 'S'},
            {'AttributeName': 'enrolled_date', 'AttributeType': 'S'}
        ],
        BillingMode='PAY_PER_REQUEST'  # 按需付费
    )
    table.wait_until_exists()
    print(f"表 {table.table_name} 已创建, ARN: {table.table_arn}")
    return table

# === 2. 插入数据 ===
def insert_student(table):
    items = [
        {
            'student_id': 'S2024001',
            'enrolled_date': '2024-09-01',
            'name': '张三',
            'age': 21,
            'major': '计算机科学',
            'gpa': Decimal('3.8'),
            'courses': {'数据库原理', '算法导论'}
        },
        {
            'student_id': 'S2024001',
            'enrolled_date': '2024-09-15',
            'name': '张三',
            'age': 21,
            'major': '计算机科学',
            'gpa': Decimal('3.9'),
            'courses': {'操作系统', '计算机网络'}
        },
        {
            'student_id': 'S2024002',
            'enrolled_date': '2024-09-01',
            'name': '李四',
            'age': 22,
            'major': '数学',
            'gpa': Decimal('3.5'),
            'courses': {'高等代数'}
        }
    ]
    
    for item in items:
        table.put_item(Item=item)
    print(f"插入 {len(items)} 条记录")

# === 3. 查询 ===
def query_students(table, student_id):
    """按分区键查询某学生的所有记录"""
    response = table.query(
        KeyConditionExpression=boto3.dynamodb.conditions.Key('student_id').eq(student_id)
    )
    print(f"\n查询 {student_id} 的记录:")
    for item in response['Items']:
        print(f"  日期: {item['enrolled_date']}, GPA: {item['gpa']}")

# === 4. 获取单条记录 ===
def get_item(table, student_id, enrolled_date):
    response = table.get_item(
        Key={
            'student_id': student_id,
            'enrolled_date': enrolled_date
        }
    )
    if 'Item' in response:
        item = response['Item']
        print(f"\n获取到: {item['name']}, GPA: {item['gpa']}")
    else:
        print("未找到记录")

# === 5. 更新记录 ===
def update_gpa(table, student_id, enrolled_date, new_gpa):
    response = table.update_item(
        Key={
            'student_id': student_id,
            'enrolled_date': enrolled_date
        },
        UpdateExpression='SET gpa = :gpa, #ts = :ts',
        ExpressionAttributeValues={
            ':gpa': Decimal(str(new_gpa)),
            ':ts': datetime.now().isoformat()
        },
        ExpressionAttributeNames={
            '#ts': 'updated_at'  # 新增字段
        },
        ReturnValues='UPDATED_NEW'
    )
    print(f"\n更新后: {response['Attributes']}")

# === 6. 使用 GSI(全局二级索引)按专业查询 ===
def create_gsi(table):
    """添加全局二级索引:按 major 查询"""
    table.update(
        AttributeDefinitions=[
            {'AttributeName': 'major', 'AttributeType': 'S'}
        ],
        GlobalSecondaryIndexUpdates=[
            {
                'Create': {
                    'IndexName': 'MajorIndex',
                    'KeySchema': [
                        {'AttributeName': 'major', 'KeyType': 'HASH'},
                        {'AttributeName': 'gpa', 'KeyType': 'RANGE'}
                    ],
                    'Projection': {'ProjectionType': 'ALL'}
                }
            }
        ]
    )
    print("GSI MajorIndex 创建中(约 1 分钟)...")

# === 主流程 ===
if __name__ == '__main__':
    try:
        table = create_table()
    except Exception:
        table = dynamodb.Table('Students')
        print("表已存在")

    insert_student(table)
    query_students(table, 'S2024001')
    get_item(table, 'S2024001', '2024-09-01')
    update_gpa(table, 'S2024002', '2024-09-01', 3.7)

预期输出

表 Students 已创建
插入 3 条记录

查询 S2024001 的记录:
  日期: 2024-09-01, GPA: 3.8
  日期: 2024-09-15, GPA: 3.9

获取到: 张三, GPA: 3.8

更新后: {'gpa': Decimal('3.7'), 'updated_at': '2024-...'}

关键点

  • DynamoDB 的 PRIMARY KEY = Partition Key (HASH) + 可选的 Sort Key (RANGE)
  • query() 需要完整 Partition Key,scan() 全表扫描(较慢)
  • GSI 允许按非主键字段查询,但最终一致
  • Decimal 类型用于精确数值(boto3 要求)
  • 集合类型(如 courses)支持 {'数据库原理', '算法导论'}

信息

路径
/tech-stacks/dynamodb/examples/Hello World - 学生表 CRUD 操作.md
更新时间
2026/5/31