探索亚马逊 DynamoDB 软件开发工具包客户端

作者: 李·汉尼根 | 2023 年 9 月 日

在使用 Amazon DynamoDB 时,开发人员可以在提供的大部分 亚马逊云科技 开发工具包中选择低级客户和高级客户端。了解这些客户端类型之间的差异对于与 DynamoDB 进行有效交互至关重要。在这篇文章中,我们探讨了低级别和高级客户的特征、用例和优势。

Dynamodb-json 与原生 JSON

要了解 DynamoDB 开发工具包客户端的复杂性,必须深入研究 DynamoDB 如何以 DynamoDB JSON 格式存储数据的根本基础。DynamoDB-JSON 是 DynamoDB 使用的一种特殊格式来以结构化方式存储数据。它通过为每个属性值引入数据类型注释来扩展 JSON 格式。

以下代码是标准 JSON 的示例:

{"mykey":"my string value"}

与 Dynamodb-JSON 比较:

{"mykey":{"S":"my string value"}}

在这种情况下,属性 “mykey” 使用数据类型 “S” 进行注释, 以表示其值为字符串。

DynamoDB 对不同类型的属性值使用特定的数据类型注释。这里, “S” 代表字符串类型。其他常见的注释包括表示数字的 “N” 、表示二进制数据的 “B” 、表示布尔值 的 “BO O L”、代表列表的 “L” 以及 用于嵌套 JSON 对象或 Map 的 “M” 。有关数据类型的完整列表,请参阅 数据类型描述符 。

低级客户端

低级客户端是 DynamoDB API 的直接接口。这使开发人员能够在精细层面上与 DynamoDB 进行交互。它需要明确指定请求参数,并提供对数据操作和 API 操作的精细控制。

低级客户端依靠数据类型注释(前面已经描述过)(也称为 令牌 )来向 DynamoDB 传达有关如何解释每个属性的信息。这些注释可用作 DynamoDB 关于与每个属性值关联的数据类型的说明。向 DynamoDB 发送数据或从中检索数据时,API 协议使用这些令牌来确保对属性值的解释准确、一致。

每个可用 的 亚马逊云科技 开发工具包 都为 DynamoDB 提供了一个低级客户端,该客户端通常被称为默认客户端。

低级客户端具有以下关键特征:

  • 提供对 DynamoDB API 操作的精细控制
  • 适用于需要低级自定义的高级用例
  • 为实现复杂的数据访问模式提供了灵活性
  • 直接表示 DynamoDB API

除了提供对 DynamoDB API 操作的精细控制外,低级客户端还提供对全套 DynamoDB API 功能的访问权限。 这包括 ExporttableTopoint inTime 和 ImportTable 等高级功能 ,这些功能允许在 DynamoDB 表和 PartiQL API 之间进行无缝数据备份和迁移,这使开发人员能够使用兼容 SQL 的查询语言与 DynamoDB 项目进行交互。

低级客户端提供的这些高级功能为 DynamoDB 中的数据管理、备份和迁移提供了强大的功能。尽管高级 SDK 为大多数常见用例提供了便利性和抽象性,但在使用这些特殊功能时,低级客户端至关重要。

高级客户端

另一方面,高级客户端是一个更加抽象和简化的接口,在与 DynamoDB 交互时可提供更高级别的抽象。它封装了许多低级细节并简化了常见任务。这减少了使用 DynamoDB 所需的代码量。

高级客户端通过自动处理低级 API 操作和数据转换,提供了一种更直观、更易于开发人员使用的方法。它抽象了数据类型注释和其他精细细节的复杂性。这使开发人员可以专注于他们的应用程序逻辑,而不是低级实现细节。

高级客户端通常提供更具声明性和面向对象的编程模型,这样可以更轻松地处理 DynamoDB 表、项目和查询。它提供自动分页、对象映射以及简化的查询和扫描操作等功能。对于大多数常见用例,建议使用高级客户端,因为它简单易用。它通过减少样板代码和提高开发人员的工作效率来简化使用 DynamoDB 的过程。它提供了自动对象映射等功能,允许您将应用程序对象直接映射到 DynamoDB 项目,从而使数据操作更加自然、更轻松。

高级客户端具有以下关键属性:

  • 通过抽象出低级细节来简化开发过程。
  • 非常适合大多数常见用例和一般应用程序开发。
  • 减少样板代码并提高开发人员的工作效率。
  • 自动执行分页和错误处理等任务。

注意:

在 Boto3 中 ,资源实例不是线程安全的,不应跨线程或进程共享。这些特殊类包含无法共享的其他元数据。建议为每个线程或进程创建新资源。

低级客户与高级客户比较的示例

为了说明低级客户端和高级客户端之间的区别,我们举例使用了两个流行的 亚马逊云科技 开发工具包: 适用于 JavaScript 的 Node.js 和适用于 Python 的 Boto 3。 我们通过检查这些语言的代码片段来展示客户端的选择如何影响复杂性和实现细节。

让我们考虑一个场景,即我们想要使用主键 user_id 从 DynamoDB 表中检索项目。

首先,我们在 Node.js 和 Python 中使用低级客户端方法探索代码:

以下代码是 Node.js 低级客户端示例:

const { DynamoDBClient, GetItemCommand } = require('@aws-sdk/client-dynamodb');

const dynamoDBClient = new DynamoDBClient({ region: "us-west-2" });

const params = {
  TableName: 'my-table',
  Key: {
    user_id: { 'S': '12345' },
  },
};

const command = new GetItemCommand(params);

dynamoDBClient.send(command)
  .then((data) => {
    console.log(data.Item);
  })
  .catch((err) => {
    console.error(err);
  });

输出:

以下是输出格式,在这里我们可以断言包含数据类型注释的 Dynamodb-JSON 输出:

{
    "user_id": {
        "S": "12345"
    },
    "last_name": {
        "S": "Whitlock"
    },
    "first_name": {
        "S": "Terry"
    },
    "phone_number": {
        "S": "555-0100"
    },
    "address": {
        "M": {
            "address_line_1": {
                "S": "123 Any Stree"
            },
            "country": {
                "S": "USA"
            },
            "address_line_2": {
                "S": "Any Town"
            }
        }
    },
    "age": {
        "N": "48"
    }
}

以下代码是 Python Boto3 的低级客户端示例:

import boto3

dynamodb_client = boto3.client('dynamodb', region_name='us-west-2')

response = dynamodb_client.get_item(
    TableName='my-table',
    Key={
        'user_id': {'S': '12345'}
    }
)

item = response['Item']
print(item)

输出:

以下是输出格式,它与之前在 Node.js 客户端中看到的 Dynamodb-JSON 格式相同:

{
    'user_id': {
        'S': '12345'
    },
    'last_name': {
        'S': 'Whitlock'
    },
    'first_name': {
        'S': 'Terry'
    },
    'phone_number': {
        'S': '555-0100'
    },
    'address': {
        'M': {
            'address_line_1': {
                'S': '123 Any Stree'
            },
            'country': {
                'S': 'USA'
            },
            'address_line_2': {
                'S': 'Any Town'
            }
        }
    },
    'age': {
        'N': '48'
    }
}

在这些示例中,低级客户端(Node.JS 和 Boto3 客户端)用于直接与 DynamoDB API 进行交互。开发人员必须明确指定参数,包括表名和检索项目的密钥。

让我们使用高级客户端来研究同样的场景。

以下代码是 Node.js 高级客户端示例:

const { DynamoDBClient } = require("@aws-sdk/client-dynamodb");
const { DynamoDBDocumentClient, GetCommand } = require("@aws-sdk/lib-dynamodb");

const client = new DynamoDBClient({ region: "us-west-2"});
const docClient = DynamoDBDocumentClient.from(client);

const params = {
    TableName: "my-table",
    Key: {
        'user_id': '12345'
    }
};

const command = new GetCommand(params);

docClient.send(command)
  .then((data) => {
    console.log(data.Item);
  })
  .catch((err) => {
    console.error(err);
  });

输出 :

以下是输出格式,这次以原生 JSON 格式返回,其中不包括数据类型注释:

{
  user_id: '12345',
  last_name: 'Whitlock',
  first_name: 'Terry',
  phone_number: '555-0100',
  address: {
    address_line_1: '123 Any Stree',
    country: 'USA',
    address_line_2: 'Any Town'
  },
  age: 48
}

以下代码是 Python Boto3 的高级客户端示例:

import boto3

dynamodb_resource = boto3.resource('dynamodb', region_name='us-west-2')

table = dynamodb_resource.Table('my-table')

response = table.get_item(
    Key={
        'user_id': '12345'
    }
)

item = response['Item']
print(item)

输出 :

此处的输出再次显示了没有数据类型注释的本机 JSON:

{
    'user_id': '12345', 
    'last_name': 'Whitlock', 
    'first_name': 'Terry', 
    'phone_number': '555-0100', 
    'address': {
        'address_line_1': '123 Any Stree', 
        'country': 'USA', 
        'address_line_2': 'Any Town'
    }, '
    age': Decimal('48')
}

在这些示例中,高级客户端(Node.js 中的 DocumentClient 和 Python 中的 boto3.resource)提供了更加抽象和简化的界面。代码更简洁,更具可读性,因为客户端会隐式处理许多低级细节,例如数据类型注释。

通过比较低级别和高级客户端示例,我们可以清楚地观察到复杂性和抽象级别的差异。高级客户端抽象出底层 DynamoDB API 的细微差别。这使开发人员能够以更直观、更简化的方式使用 DynamoDB。

在 JSON 格式之间转换

在与 DynamoDB 交互时,您可能需要将 JSON 对象转换为 DynamoDB-JSON 格式,反之亦然。这就是实用程序包中的 marshall 和 unmarshall 函数变得有用的地方。

马歇尔函数用于将 JSON 对象转换为 Dynamodb-JSON 属性值格式。它接收一个普通 JSON 对象并返回该对象的编组表示形式,以便将属性值转换为适当的 DynamoDB 数据类型。这在准备要存储在 DynamoDB 中的数据时特别有用,因为它可以确保数据符合预期格式。

另一方面,unmarshall 函数用于将 Dynamodb-JSON 属性值格式转换回普通的 JSON 对象。它接收通常从 DynamoDB 操作中检索到的 DynamoDB-JSON 响应对象,并将属性值转换为相应的 JSON 数据类型。这使您可以在代码中以更熟悉、更方便的方式处理数据。

虽然 Node.js 函数被称为 marshall 和 unmarshall,但在 Python 的 Boto3 库中,使用序列化和反序列化操作可以实现类似的功能。这些操作执行与 Node.js 对应操作相同的任务,但名称不同。

序列化操作将 Python 对象转换为 DynamoDB 属性值格式。这样就可以将其存储在 DynamoDB 中了。

反序列化操作将 DynamoDB 属性值格式转换回 Python 对象。这样可以在 Python 应用程序中无缝处理和利用检索到的数据。

nodeJS 示例

以下代码是 Node.js 示例(包: @aws-sdk/util-d ynamodb):

const { DynamoDBClient } = require('@aws-sdk/client-dynamodb');
const { marshall, unmarshall } = require('@aws-sdk/util-dynamodb');

const REGION = 'us-west-2';

const dynamoDBClient = new DynamoDBClient({ region: REGION });

// Marshall (Serialize) Example
const itemToStore = {
  user_id: '12345',
  first_name: 'Terry',
  age: 48,
};

const marshalledItem = marshall(itemToStore);

const putItemParams = {
  TableName: 'my-table',
  Item: marshalledItem,
};

dynamoDBClient.putItem(putItemParams)
  .then(() => {
    console.log('Item stored successfully.');
  })
  .catch((err) => {
    console.error('Error storing item:', err);
  });

// Unmarshall (Deserialize) Example
const getItemParams = {
  TableName: 'my-table',
  Key: {
    user_id: { S: '12345' },
  },
};

dynamoDBClient.getItem(getItemParams)
  .then((data) => {
    const retrievedItem = unmarshall(data.Item);
    console.log(retrievedItem);
  })
  .catch((err) => {
    console.error(err);
  });

在前面的示例中,我们演示了使用适用于 JavaScript 的 亚马逊云科技 开发工具包 V3 进行编组(序列化)和反编组(反序列化)。

编组示例概述

编组包括以下步骤:

  1. 让 JavaScript 对象 ItemToStore 表示要存储在 DynamoDB 中的项目。
  2. 使用 马歇尔 函数将此对象转换为 DynamoDB 属性值格式 (MarshalledItem)。
  3. 将编组后的物品传递给 PutItem 操作以将其存储在 DynamoDB 中。

解组示例概述

解密包括以下步骤:

  1. 让 getitemParams 对象指定表名和密钥,以便从 DynamoDB 检索项目。
  2. 调用 getItem 操作系统。
  3. 获取响应数据。
  4. 使用 unmarshall 函数将 DynamoDB 属性值格式转换为普通的 JavaScript 对象(retrieveDitem)。
  5. 将检索到的项目记录到控制台。

您可以使用马歇尔和 非 马歇尔 函数在 DynamoDB 属性值格式和 JavaScript 对象之间转换数据。这便于与 DynamoDB 无缝集成,并简化了 Node.js 应用程序中的数据处理。

Boto3 示例

以下代码是 Boto3 示例(软件包:boto3.dynamod b .types):

import boto3 from boto3.dynamodb.types 
import TypeSerializer, TypeDeserializer

REGION = 'us-west-2'

dynamodb_client = boto3.client('dynamodb', region_name=REGION)
# Serialize (Marshal) Example
item_to_store = {
    'user_id': '12345',
    'first_name': 'Terry',
    'age': 48,
}

serializer = TypeSerializer()

serialized_item = serializer.serialize(item_to_store)

put_item_params = {
    'TableName': 'my-table',
    'Item': serialized_item,
}

dynamodb_client.put_item(**put_item_params)

deserializer = TypeDeserializer()

get_item_params = {
    'TableName': 'my-table',
    'Key': {
        'user_id': {'S': '12345'},
    },
}

response = dynamodb_client.get_item(**get_item_params)
retrieved_item = deserializer.deserialize(response['Item'])
print(retrieved_item)

在前面的示例中,我们使用适用于 Python 的 Boto3 库演示了序列化(序列化)和反序列化(反序列化)。

序列化示例

序列化包括以下步骤:

  1. 让 Python 字典 item_to_store 表示要存储在 DynamoDB 中的项目。
  2. 创建 TypeSerializer 对象并使用其序列化方法将字典转换为 DynamoDB 属性值格式(serialized_item)。
  3. 将序列化的项目传递给 put_item 操作以将其存储在 DynamoDB 中。

反序列化示例

反序列化包括以下步骤:

  1. 创建类型反序列化器对象。
  2. 在 get_item_params 字典中指定表名和键以从 DynamoDB 检索项目。
  3. 调用 get_item 操作。
  4. 获取包含序列化项的响应。
  5. 使用 TypeDeserializer 对象的反序列化方法将序列化的项目转换回 Python 字典(retrieved_item)。
  6. 打印检索到的项目。

您可以使用 Boto3 提供的序列化和反序列化函数在 DynamoDB 属性值格式和 Python 对象之间转换数据。这样可以与 DynamoDB 无缝集成,并简化 Python 应用程序中的数据处理。

DynamoDB SDK 编程语言概述

下表提供了总体概述,可能不包括每种编程语言的所有可用的 DynamoDB 客户端。

Programming language High-level clients Low-level clients
JavaScript/Node V2 DocumentClient DynamoDBClient
JavaScript/Node V3 DocumentClient DynamoDBClient
Python Boto3 Resource Table Client
Java SDK V1 DynamoDBMapper AmazonDynamoDBClient
Java SDK V2 EnchancedClient DynamoDbClient
.NET (C#) DocumentModel AmazonDynamoDBClient
Ruby Aws::Record Aws::DynamoDB::Client
PHP DynamoDb\Marshaler DynamoDb\DynamoDbClient
Go dynamodbattribute dynamodb
Rust N/A aws_sdk_dynamodb :: Client
Swift 亚马逊云科技DynamoDBObjectMapper 亚马逊云科技DynamoDB

结论

在低级客户端和高级客户端之间进行选择取决于应用程序的特定要求。

低级客户端提供精细控制和灵活性。这使其适用于高级用例和微调的自定义。高级客户端抽象了复杂性,为常见用例提供了更简单、更高效的体验。

了解这两种客户端类型的特征、用例和优势使开发人员能够做出明智的决策,并使用最合适的客户端进行他们的 DynamoDB 交互。在选择最适合您需求的客户端时,必须考虑所需的控制级别、数据访问模式的复杂性以及所需的开发体验等因素。

准备好将您的开发项目提升到一个新的水平了吗?访问 亚马逊云科技 开发 者工具 ,发现丰富的资源、教程和见解,它们将帮助您充分利用 亚马逊云科技 的全部力量。而且,千万不要错过 今天前往 亚马逊云科技 开发者工具博客,为您的项目增光添彩,从而释放 亚马逊云科技 的潜力并提高您的开发 技能!


作者简介

Lee Hannigan ,Sr. DynamoDB 专家 SA。Lee 在过去 4 年中一直是 DynamoDB 专家,拥有深厚的大数据技术背景以及与创新型初创公司合作获得的宝贵见解,他为欧洲、中东和非洲地区的 亚马逊云科技 客户带来了丰富的知识。Lee 热衷于帮助 亚马逊云科技 客户扩展应用程序,他的专业知识在于利用 DynamoDB 和无服务器技术来实现最佳性能和效率。通过提供量身定制的解决方案和指导,Lee 成功地帮助数百家组织充分发挥 DynamoDB 的潜力并采用无服务器架构。凭借以客户为中心的方法和对 亚马逊云科技 服务的深刻理解,Lee 致力于帮助企业在云计算世界中蓬勃发展。


*前述特定亚马逊云科技生成式人工智能相关的服务仅在亚马逊云科技海外区域可用,亚马逊云科技中国仅为帮助您发展海外业务和/或了解行业前沿技术选择推荐该服务。