Node.js 的亚马逊QLDB驱动程序 — 快速入门教程 - 亚马逊 Quantum Ledger 数据库(亚马逊QLDB)

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

Node.js 的亚马逊QLDB驱动程序 — 快速入门教程

重要

终止支持通知:现有客户可以在2025年7月31日终止支持QLDB之前使用亚马逊。有关更多详细信息,请参阅将亚马逊QLDB账本迁移到亚马逊 Aurora Postgr SQL e。

在本教程中,您将学习如何使用适用于 Node.js 的 Amazon QLDB 驱动程序设置简单的应用程序。本指南包括安装驱动程序的步骤,以及基本创建、读取、更新 JavaScript 和删除 (CRUD) 操作的简短和 TypeScript 代码示例。有关在完整示例应用程序中演示这些操作的更深入的示例,请参阅 Node.js 教程

注意

在适用的情况下,某些步骤对每个支持的 Node.js QLDB 驱动程序主要版本都有不同的代码示例。

先决条件

在开始之前,请务必执行以下操作:

  1. 请为 Node.js 驱动程序完成(先决条件 如果尚未执行此操作)。这包括注册 AWS、授予开发所需的编程访问权限以及安装 Node.js。

  2. 创建一个名为 quick-start 分类账。

    要了解如何创建分类账,请参阅控制台入门中的 Amazon QLDB 账本的基本操作第 1 步:创建新的分类账

如果您正在使用 TypeScript,则还必须执行以下设置步骤。

要安装 TypeScript
  1. 安装 TypeScript 软件包。该QLDB驱动程序在 TypeScript 3.8.x 上运行。

    $ npm install --global typescript@3.8.0
  2. 安装软件包后,运行以下命令以确保 TypeScript 编译器已安装。

    $ tsc --version

要按以下步骤运行代码,请注意必须先将 TypeScript 文件转换为可执行 JavaScript 代码,如下所示。

$ tsc app.ts; node app.js

第 1 步:设置您的 项目

首先,您需要设置您的 Node.js 项目。

  1. 为应用程序创建一个文件夹。

    $ mkdir myproject $ cd myproject
  2. 要初始化您的项目,请输入以下 npm 命令并回答安装过程中提出的问题。您可以对大多数问题使用默认值。

    $ npm init
  3. 安装 Node.js 的亚马逊QLDB驱动程序。

    • 使用版本 3.x

      $ npm install amazon-qldb-driver-nodejs --save
    • 使用版本 2.x

      $ npm install amazon-qldb-driver-nodejs@2.2.0 --save
    • 使用版本 1.x

      $ npm install amazon-qldb-driver-nodejs@1.0.0 --save
  4. 安装驱动程序的对等依赖项。

    • 使用版本 3.x

      $ npm install @aws-sdk/client-qldb-session --save $ npm install ion-js --save $ npm install jsbi --save
    • 使用版本 2.x 或 1.x

      $ npm install aws-sdk --save $ npm install ion-js@4.0.0 --save $ npm install jsbi@3.1.1 --save
  5. 创建一个名为 JavaScript、或app.jsapp.ts为的新文件 TypeScript。

    然后,按以下步骤逐步添加代码示例,尝试一些基本CRUD操作。或者,您可以跳过本 step-by-step 教程,改为运行完整的应用程序

第 2 步:初始化驱动程序

初始化连接到名为 quick-start 的分类账的驱动程序实例。将以下代码添加到您的 app.jsapp.ts 文件。

JavaScript
var qldb = require('amazon-qldb-driver-nodejs'); var https = require('https'); function main() { const maxConcurrentTransactions = 10; const retryLimit = 4; const agentForQldb = new https.Agent({ maxSockets: maxConcurrentTransactions }); const lowLevelClientHttpOptions = { httpAgent: agentForQldb } const serviceConfigurationOptions = { region: "us-east-1" }; // Use driver's default backoff function for this example (no second parameter provided to RetryConfig) var retryConfig = new qldb.RetryConfig(retryLimit); var driver = new qldb.QldbDriver("quick-start", serviceConfigurationOptions, lowlevelClientHttpOptions, maxConcurrentTransactions, retryConfig); } main();
TypeScript
import { Agent } from "https"; import { NodeHttpHandlerOptions } from "@aws-sdk/node-http-handler"; import { QLDBSessionClientConfig } from "@aws-sdk/client-qldb-session"; import { QldbDriver, RetryConfig } from "amazon-qldb-driver-nodejs"; function main(): void { const maxConcurrentTransactions: number = 10; const agentForQldb: Agent = new Agent({ maxSockets: maxConcurrentTransactions }); const lowLevelClientHttpOptions: NodeHttpHandlerOptions = { httpAgent: agentForQldb }; const serviceConfigurationOptions: QLDBSessionClientConfig = { region: "us-east-1" }; const retryLimit: number = 4; // Use driver's default backoff function for this example (no second parameter provided to RetryConfig) const retryConfig: RetryConfig = new RetryConfig(retryLimit); const driver: QldbDriver = new QldbDriver("quick-start", serviceConfigurationOptions, lowLevelClientHttpOptions, maxConcurrentTransactions, retryConfig); } if (require.main === module) { main(); }
注意
  • 在此代码示例中,替换 us-east-1 以及你在 AWS 区域 哪里创建账本。

  • 为简单起见,本指南中的其余代码示例使用具有默认设置的驱动程序,如以下版本 1.x 示例中所述。您也可以使用您自己的驱动程序实例来代替自定义 RetryConfig

JavaScript
var qldb = require('amazon-qldb-driver-nodejs'); var https = require('https'); function main() { var maxConcurrentTransactions = 10; var retryLimit = 4; var agentForQldb = new https.Agent({ keepAlive: true, maxSockets: maxConcurrentTransactions }); var serviceConfigurationOptions = { region: "us-east-1", httpOptions: { agent: agentForQldb } }; // Use driver's default backoff function for this example (no second parameter provided to RetryConfig) var retryConfig = new qldb.RetryConfig(retryLimit); var driver = new qldb.QldbDriver("quick-start", serviceConfigurationOptions, maxConcurrentTransactions, retryConfig); } main();
TypeScript
import { QldbDriver, RetryConfig } from "amazon-qldb-driver-nodejs"; import { ClientConfiguration } from "aws-sdk/clients/acm"; import { Agent } from "https"; function main(): void { const maxConcurrentTransactions: number = 10; const agentForQldb: Agent = new Agent({ keepAlive: true, maxSockets: maxConcurrentTransactions }); const serviceConfigurationOptions: ClientConfiguration = { region: "us-east-1", httpOptions: { agent: agentForQldb } }; const retryLimit: number = 4; // Use driver's default backoff function for this example (no second parameter provided to RetryConfig) const retryConfig: RetryConfig = new RetryConfig(retryLimit); const driver: QldbDriver = new QldbDriver("quick-start", serviceConfigurationOptions, maxConcurrentTransactions, retryConfig); } if (require.main === module) { main(); }
注意
  • 在此代码示例中,替换 us-east-1 以及你在 AWS 区域 哪里创建账本。

  • 版本 2.x 引入了用于初始化 QldbDriver 的新可选参数 RetryConfig

  • 为简单起见,本指南中的其余代码示例使用具有默认设置的驱动程序,如以下版本 1.x 示例中所述。您也可以使用您自己的驱动程序实例来代替自定义 RetryConfig

  • 此代码示例初始化一个驱动程序,该驱动程序通过设置 keep-alive 选项来重用现有连接。要了解更多信息,请参阅 设置建议 了解 Node.js 驱动程序。

JavaScript
const qldb = require('amazon-qldb-driver-nodejs'); function main() { // Use default settings const driver = new qldb.QldbDriver("quick-start"); } main();
TypeScript
import { QldbDriver } from "amazon-qldb-driver-nodejs"; function main(): void { // Use default settings const driver: QldbDriver = new QldbDriver("quick-start"); } if (require.main === module) { main(); }
注意

您可以设置 AWS_REGION 环境变量以确定区域。有关更多信息,请参阅《AWS SDK for JavaScript 开发人员指南》中的 设置 AWS 区域

第 3 步:创建表和索引

以下代码示例显示如何运行 CREATE TABLECREATE INDEX 语句。

  1. 添加以下函数,创建名为 People 的表。

    JavaScript
    async function createTable(txn) { await txn.execute("CREATE TABLE People"); }
    TypeScript
    async function createTable(txn: TransactionExecutor): Promise<void> { await txn.execute("CREATE TABLE People"); }
  2. 添加以下函数,为 People 表中的 firstName 字段创建索引。索引是优化查询性能和帮助限制乐观并发控制 (OCC) 冲突异常所必需的。

    JavaScript
    async function createIndex(txn) { await txn.execute("CREATE INDEX ON People (firstName)"); }
    TypeScript
    async function createIndex(txn: TransactionExecutor): Promise<void> { await txn.execute("CREATE INDEX ON People (firstName)"); }
  3. main 函数中,你先调用 createTable,然后调用 createIndex

    JavaScript
    const qldb = require('amazon-qldb-driver-nodejs'); async function main() { // Use default settings const driver = new qldb.QldbDriver("quick-start"); await driver.executeLambda(async (txn) => { console.log("Create table People"); await createTable(txn); console.log("Create index on firstName"); await createIndex(txn); }); driver.close(); } main();
    TypeScript
    import { QldbDriver, TransactionExecutor } from "amazon-qldb-driver-nodejs"; async function main(): Promise<void> { // Use default settings const driver: QldbDriver = new QldbDriver("quick-start"); await driver.executeLambda(async (txn: TransactionExecutor) => { console.log("Create table People"); await createTable(txn); console.log("Create index on firstName"); await createIndex(txn); }); driver.close(); } if (require.main === module) { main(); }
  4. 运行代码以创建表和索引。

    JavaScript
    $ node app.js
    TypeScript
    $ tsc app.ts; node app.js

第 4 步:插入文档

以下代码示例显示如何运行 INSERT 语句。QLDB支持 P artiQL 查询语言(SQL兼容)和 A mazon Ion 数据格式(的超集)。JSON

  1. 添加以下函数,在 People 表格中插入文档。

    JavaScript
    async function insertDocument(txn) { const person = { firstName: "John", lastName: "Doe", age: 42 }; await txn.execute("INSERT INTO People ?", person); }
    TypeScript
    async function insertDocument(txn: TransactionExecutor): Promise<void> { const person: Record<string, any> = { firstName: "John", lastName: "Doe", age: 42 }; await txn.execute("INSERT INTO People ?", person); }

    此示例使用问号(?)作为变量占位符,将文档信息传递给语句。该 execute 方法同时支持 Amazon Ion 类型和 Node.js 本机类型。

    提示

    要使用单个 INSERT 语句插入多个文档,可以向该语句传递一个列表类型的参数,如下所示。

    // people is a list txn.execute("INSERT INTO People ?", people);

    传递 Ion 列表时,不要将变量占位符(?)括在双尖括号(<<...>>)内。在手动 PartiQL 语句中,双尖括号表示名为bag的无序集合。

  2. main 函数中,移除 createTablecreateIndex 调用,然后向添加调用 insertDocument

    JavaScript
    const qldb = require('amazon-qldb-driver-nodejs'); async function main() { // Use default settings const driver = new qldb.QldbDriver("quick-start"); await driver.executeLambda(async (txn) => { console.log("Insert document"); await insertDocument(txn); }); driver.close(); } main();
    TypeScript
    import { QldbDriver, TransactionExecutor } from "amazon-qldb-driver-nodejs"; async function main(): Promise<void> { // Use default settings const driver: QldbDriver = new QldbDriver("quick-start"); await driver.executeLambda(async (txn: TransactionExecutor) => { console.log("Insert document"); await insertDocument(txn); }); driver.close(); } if (require.main === module) { main(); }

第 5 步:查询文档

以下代码示例显示如何运行 SELECT 语句。

  1. 添加以下函数,用于从 People 表格中查询文档。

    JavaScript
    async function fetchDocuments(txn) { return await txn.execute("SELECT firstName, age, lastName FROM People WHERE firstName = ?", "John"); }
    TypeScript
    async function fetchDocuments(txn: TransactionExecutor): Promise<dom.Value[]> { return (await txn.execute("SELECT firstName, age, lastName FROM People WHERE firstName = ?", "John")).getResultList(); }
  2. main 函数中,在对的调用 fetchDocuments 之后添加以下调用 insertDocument

    JavaScript
    const qldb = require('amazon-qldb-driver-nodejs'); async function main() { // Use default settings const driver = new qldb.QldbDriver("quick-start"); var resultList = await driver.executeLambda(async (txn) => { console.log("Insert document"); await insertDocument(txn); console.log("Fetch document"); var result = await fetchDocuments(txn); return result.getResultList(); }); // Pretty print the result list console.log("The result List is ", JSON.stringify(resultList, null, 2)); driver.close(); } main();
    TypeScript
    import { QldbDriver, TransactionExecutor } from "amazon-qldb-driver-nodejs"; import { dom } from "ion-js"; async function main(): Promise<void> { // Use default settings const driver: QldbDriver = new QldbDriver("quick-start"); const resultList: dom.Value[] = await driver.executeLambda(async (txn: TransactionExecutor) => { console.log("Insert document"); await insertDocument(txn); console.log("Fetch document"); return await fetchDocuments(txn); }); // Pretty print the result list console.log("The result List is ", JSON.stringify(resultList, null, 2)); driver.close(); } if (require.main === module) { main(); }

第 6 步:更新文档

以下代码示例显示如何运行 UPDATE 语句。

  1. 添加以下函数,通过修改 lastName"Stiles" 来更新 People 表中的文档。

    JavaScript
    async function updateDocuments(txn) { await txn.execute("UPDATE People SET lastName = ? WHERE firstName = ?", "Stiles", "John"); }
    TypeScript
    async function updateDocuments(txn: TransactionExecutor): Promise<void> { await txn.execute("UPDATE People SET lastName = ? WHERE firstName = ?", "Stiles", "John"); }
  2. main 函数中,在对的调用 updateDocuments 之后添加以下调用 fetchDocuments。然后,再次调用 fetchDocuments 来查看更新的结果。

    JavaScript
    const qldb = require('amazon-qldb-driver-nodejs'); async function main() { // Use default settings const driver = new qldb.QldbDriver("quick-start"); var resultList = await driver.executeLambda(async (txn) => { console.log("Insert document"); await insertDocument(txn); console.log("Fetch document"); await fetchDocuments(txn); console.log("Update document"); await updateDocuments(txn); console.log("Fetch document after update"); var result = await fetchDocuments(txn); return result.getResultList(); }); // Pretty print the result list console.log("The result List is ", JSON.stringify(resultList, null, 2)); driver.close(); } main();
    TypeScript
    import { QldbDriver, TransactionExecutor } from "amazon-qldb-driver-nodejs"; import { dom } from "ion-js"; async function main(): Promise<void> { // Use default settings const driver: QldbDriver = new QldbDriver("quick-start"); const resultList: dom.Value[] = await driver.executeLambda(async (txn: TransactionExecutor) => { console.log("Insert document"); await insertDocument(txn); console.log("Fetch document"); await fetchDocuments(txn); console.log("Update document"); await updateDocuments(txn); console.log("Fetch document after update"); return await fetchDocuments(txn); }); // Pretty print the result list console.log("The result List is ", JSON.stringify(resultList, null, 2)); driver.close(); } if (require.main === module) { main(); }
  3. 运行代码以插入、查询和更新文档。

    JavaScript
    $ node app.js
    TypeScript
    $ tsc app.ts; node app.js

运行完整的应用程序

以下代码示例是完整版本的 app.jsapp.ts。您还可以从头到尾运行此代码,而不必单独执行前面的步骤。此应用程序演示了对名为的账本的一些基本CRUD操作quick-start

注意

在运行此代码之前,请确保 quick-start 分类账中还没有名为 People 的活动表。

JavaScript
const qldb = require('amazon-qldb-driver-nodejs'); async function createTable(txn) { await txn.execute("CREATE TABLE People"); } async function createIndex(txn) { await txn.execute("CREATE INDEX ON People (firstName)"); } async function insertDocument(txn) { const person = { firstName: "John", lastName: "Doe", age: 42 }; await txn.execute("INSERT INTO People ?", person); } async function fetchDocuments(txn) { return await txn.execute("SELECT firstName, age, lastName FROM People WHERE firstName = ?", "John"); } async function updateDocuments(txn) { await txn.execute("UPDATE People SET lastName = ? WHERE firstName = ?", "Stiles", "John"); } async function main() { // Use default settings const driver = new qldb.QldbDriver("quick-start"); var resultList = await driver.executeLambda(async (txn) => { console.log("Create table People"); await createTable(txn); console.log("Create index on firstName"); await createIndex(txn); console.log("Insert document"); await insertDocument(txn); console.log("Fetch document"); await fetchDocuments(txn); console.log("Update document"); await updateDocuments(txn); console.log("Fetch document after update"); var result = await fetchDocuments(txn); return result.getResultList(); }); // Pretty print the result list console.log("The result List is ", JSON.stringify(resultList, null, 2)); driver.close(); } main();
TypeScript
import { QldbDriver, TransactionExecutor } from "amazon-qldb-driver-nodejs"; import { dom } from "ion-js"; async function createTable(txn: TransactionExecutor): Promise<void> { await txn.execute("CREATE TABLE People"); } async function createIndex(txn: TransactionExecutor): Promise<void> { await txn.execute("CREATE INDEX ON People (firstName)"); } async function insertDocument(txn: TransactionExecutor): Promise<void> { const person: Record<string, any> = { firstName: "John", lastName: "Doe", age: 42 }; await txn.execute("INSERT INTO People ?", person); } async function fetchDocuments(txn: TransactionExecutor): Promise<dom.Value[]> { return (await txn.execute("SELECT firstName, age, lastName FROM People WHERE firstName = ?", "John")).getResultList(); } async function updateDocuments(txn: TransactionExecutor): Promise<void> { await txn.execute("UPDATE People SET lastName = ? WHERE firstName = ?", "Stiles", "John"); }; async function main(): Promise<void> { // Use default settings const driver: QldbDriver = new QldbDriver("quick-start"); const resultList: dom.Value[] = await driver.executeLambda(async (txn: TransactionExecutor) => { console.log("Create table People"); await createTable(txn); console.log("Create index on firstName"); await createIndex(txn); console.log("Insert document"); await insertDocument(txn); console.log("Fetch document"); await fetchDocuments(txn); console.log("Update document"); await updateDocuments(txn); console.log("Fetch document after update"); return await fetchDocuments(txn); }); // Pretty print the result list console.log("The result List is ", JSON.stringify(resultList, null, 2)); driver.close(); } if (require.main === module) { main(); }

要运行完整的应用程序,请输入以下命令。

JavaScript
$ node app.js
TypeScript
$ tsc app.ts; node app.js