步骤 3:创建表、索引与示例数据 - 亚马逊 Quantum Ledger 数据库(亚马逊QLDB)

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

步骤 3:创建表、索引与示例数据

重要

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

当您的Amazon QLDB 账本处于活动状态并接受连接时,您可以开始创建有关车辆、车主和注册信息的数据表。创建表和索引后,可以向其中加载数据。

在此步骤中,您将在vehicle-registration分类账中创建四个表格:

  • VehicleRegistration

  • Vehicle

  • Person

  • DriversLicense

您还可创建以下索引。

表名称 字段
VehicleRegistration VIN
VehicleRegistration LicensePlateNumber
Vehicle VIN
Person GovId
DriversLicense LicenseNumber
DriversLicense PersonId

插入示例数据时,首先要在 Person 表格中插入文档。然后使用系统分配的、来自每个Person文档的id填充适当VehicleRegistrationDriversLicense文档中的相应文档。

提示

最佳做法是使用系统分配的 id 文档作为外键。虽然您可以定义作为唯一标识符的字段(例如车辆VIN),但文档的真正唯一标识符是其唯一标识符id。字段都包含在文档元数据中,您可以在提交视图(系统定义的表格视图)中对其进行查询。

有关中视图的更多信息QLDB,请参阅核心概念。了解有关元数据的更多信息,请参阅 查询文档元数据

创建表和索引
  1. 使用以下程序(CreateTable.ts)以创建前面提到的表。

    /* * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: MIT-0 * * Permission is hereby granted, free of charge, to any person obtaining a copy of this * software and associated documentation files (the "Software"), to deal in the Software * without restriction, including without limitation the rights to use, copy, modify, * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ import { QldbDriver, Result, TransactionExecutor } from "amazon-qldb-driver-nodejs"; import { getQldbDriver } from "./ConnectToLedger"; import { DRIVERS_LICENSE_TABLE_NAME, PERSON_TABLE_NAME, VEHICLE_REGISTRATION_TABLE_NAME, VEHICLE_TABLE_NAME } from "./qldb/Constants"; import { error, log } from "./qldb/LogUtil"; /** * Create multiple tables in a single transaction. * @param txn The {@linkcode TransactionExecutor} for lambda execute. * @param tableName Name of the table to create. * @returns Promise which fulfills with the number of changes to the database. */ export async function createTable(txn: TransactionExecutor, tableName: string): Promise<number> { const statement: string = `CREATE TABLE ${tableName}`; return await txn.execute(statement).then((result: Result) => { log(`Successfully created table ${tableName}.`); return result.getResultList().length; }); } /** * Create tables in a QLDB ledger. * @returns Promise which fulfills with void. */ const main = async function(): Promise<void> { try { const qldbDriver: QldbDriver = getQldbDriver(); await qldbDriver.executeLambda(async (txn: TransactionExecutor) => { Promise.all([ createTable(txn, VEHICLE_REGISTRATION_TABLE_NAME), createTable(txn, VEHICLE_TABLE_NAME), createTable(txn, PERSON_TABLE_NAME), createTable(txn, DRIVERS_LICENSE_TABLE_NAME) ]); }); } catch (e) { error(`Unable to create tables: ${e}`); } } if (require.main === module) { main(); }
    注意

    该程序演示了如何在QLDB驱动程序实例中使用该executeLambda函数。在此示例中,您使用 lambda 表达式在单个事务中运行多个CREATE TABLE PartiQL 语句

    该执行函数采用隐式启动事务,运行 lambda 中的所有语句,然后自动提交事务。

  2. 要运行编译后的程序,请输入以下命令。

    node dist/CreateTable.js
  3. 如前所述,使用以下程序(CreateIndex.ts),以在表上创建索引。

    /* * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: MIT-0 * * Permission is hereby granted, free of charge, to any person obtaining a copy of this * software and associated documentation files (the "Software"), to deal in the Software * without restriction, including without limitation the rights to use, copy, modify, * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ import { QldbDriver, TransactionExecutor } from "amazon-qldb-driver-nodejs"; import { getQldbDriver } from "./ConnectToLedger"; import { DRIVERS_LICENSE_TABLE_NAME, GOV_ID_INDEX_NAME, LICENSE_NUMBER_INDEX_NAME, LICENSE_PLATE_NUMBER_INDEX_NAME, PERSON_ID_INDEX_NAME, PERSON_TABLE_NAME, VEHICLE_REGISTRATION_TABLE_NAME, VEHICLE_TABLE_NAME, VIN_INDEX_NAME } from "./qldb/Constants"; import { error, log } from "./qldb/LogUtil"; /** * Create an index for a particular table. * @param txn The {@linkcode TransactionExecutor} for lambda execute. * @param tableName Name of the table to add indexes for. * @param indexAttribute Index to create on a single attribute. * @returns Promise which fulfills with the number of changes to the database. */ export async function createIndex( txn: TransactionExecutor, tableName: string, indexAttribute: string ): Promise<number> { const statement: string = `CREATE INDEX on ${tableName} (${indexAttribute})`; return await txn.execute(statement).then((result) => { log(`Successfully created index ${indexAttribute} on table ${tableName}.`); return result.getResultList().length; }); } /** * Create indexes on tables in a particular ledger. * @returns Promise which fulfills with void. */ const main = async function(): Promise<void> { try { const qldbDriver: QldbDriver = getQldbDriver(); await qldbDriver.executeLambda(async (txn: TransactionExecutor) => { Promise.all([ createIndex(txn, PERSON_TABLE_NAME, GOV_ID_INDEX_NAME), createIndex(txn, VEHICLE_TABLE_NAME, VIN_INDEX_NAME), createIndex(txn, VEHICLE_REGISTRATION_TABLE_NAME, VIN_INDEX_NAME), createIndex(txn, VEHICLE_REGISTRATION_TABLE_NAME, LICENSE_PLATE_NUMBER_INDEX_NAME), createIndex(txn, DRIVERS_LICENSE_TABLE_NAME, PERSON_ID_INDEX_NAME), createIndex(txn, DRIVERS_LICENSE_TABLE_NAME, LICENSE_NUMBER_INDEX_NAME) ]); }); } catch (e) { error(`Unable to create indexes: ${e}`); } } if (require.main === module) { main(); }
  4. 要运行编译后的程序,请输入以下命令。

    node dist/CreateIndex.js
将样本数据加载到表中
  1. 审查以下 .ts 文件。

    1. SampleData.ts - 包含您插入到 vehicle-registration 表中的示例数据。

      /* * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: MIT-0 * * Permission is hereby granted, free of charge, to any person obtaining a copy of this * software and associated documentation files (the "Software"), to deal in the Software * without restriction, including without limitation the rights to use, copy, modify, * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ import { Decimal } from "ion-js"; const EMPTY_SECONDARY_OWNERS: object[] = []; export const DRIVERS_LICENSE = [ { PersonId: "", LicenseNumber: "LEWISR261LL", LicenseType: "Learner", ValidFromDate: new Date("2016-12-20"), ValidToDate: new Date("2020-11-15") }, { PersonId: "", LicenseNumber : "LOGANB486CG", LicenseType: "Probationary", ValidFromDate : new Date("2016-04-06"), ValidToDate : new Date("2020-11-15") }, { PersonId: "", LicenseNumber : "744 849 301", LicenseType: "Full", ValidFromDate : new Date("2017-12-06"), ValidToDate : new Date("2022-10-15") }, { PersonId: "", LicenseNumber : "P626-168-229-765", LicenseType: "Learner", ValidFromDate : new Date("2017-08-16"), ValidToDate : new Date("2021-11-15") }, { PersonId: "", LicenseNumber : "S152-780-97-415-0", LicenseType: "Probationary", ValidFromDate : new Date("2015-08-15"), ValidToDate : new Date("2021-08-21") } ]; export const PERSON = [ { FirstName : "Raul", LastName : "Lewis", DOB : new Date("1963-08-19"), Address : "1719 University Street, Seattle, WA, 98109", GovId : "LEWISR261LL", GovIdType : "Driver License" }, { FirstName : "Brent", LastName : "Logan", DOB : new Date("1967-07-03"), Address : "43 Stockert Hollow Road, Everett, WA, 98203", GovId : "LOGANB486CG", GovIdType : "Driver License" }, { FirstName : "Alexis", LastName : "Pena", DOB : new Date("1974-02-10"), Address : "4058 Melrose Street, Spokane Valley, WA, 99206", GovId : "744 849 301", GovIdType : "SSN" }, { FirstName : "Melvin", LastName : "Parker", DOB : new Date("1976-05-22"), Address : "4362 Ryder Avenue, Seattle, WA, 98101", GovId : "P626-168-229-765", GovIdType : "Passport" }, { FirstName : "Salvatore", LastName : "Spencer", DOB : new Date("1997-11-15"), Address : "4450 Honeysuckle Lane, Seattle, WA, 98101", GovId : "S152-780-97-415-0", GovIdType : "Passport" } ]; export const VEHICLE = [ { VIN : "1N4AL11D75C109151", Type : "Sedan", Year : 2011, Make : "Audi", Model : "A5", Color : "Silver" }, { VIN : "KM8SRDHF6EU074761", Type : "Sedan", Year : 2015, Make : "Tesla", Model : "Model S", Color : "Blue" }, { VIN : "3HGGK5G53FM761765", Type : "Motorcycle", Year : 2011, Make : "Ducati", Model : "Monster 1200", Color : "Yellow" }, { VIN : "1HVBBAANXWH544237", Type : "Semi", Year : 2009, Make : "Ford", Model : "F 150", Color : "Black" }, { VIN : "1C4RJFAG0FC625797", Type : "Sedan", Year : 2019, Make : "Mercedes", Model : "CLK 350", Color : "White" } ]; export const VEHICLE_REGISTRATION = [ { VIN : "1N4AL11D75C109151", LicensePlateNumber : "LEWISR261LL", State : "WA", City : "Seattle", ValidFromDate : new Date("2017-08-21"), ValidToDate : new Date("2020-05-11"), PendingPenaltyTicketAmount : new Decimal(9025, -2), Owners : { PrimaryOwner : { PersonId : "" }, SecondaryOwners : EMPTY_SECONDARY_OWNERS } }, { VIN : "KM8SRDHF6EU074761", LicensePlateNumber : "CA762X", State : "WA", City : "Kent", PendingPenaltyTicketAmount : new Decimal(13075, -2), ValidFromDate : new Date("2017-09-14"), ValidToDate : new Date("2020-06-25"), Owners : { PrimaryOwner : { PersonId : "" }, SecondaryOwners : EMPTY_SECONDARY_OWNERS } }, { VIN : "3HGGK5G53FM761765", LicensePlateNumber : "CD820Z", State : "WA", City : "Everett", PendingPenaltyTicketAmount : new Decimal(44230, -2), ValidFromDate : new Date("2011-03-17"), ValidToDate : new Date("2021-03-24"), Owners : { PrimaryOwner : { PersonId : "" }, SecondaryOwners : EMPTY_SECONDARY_OWNERS } }, { VIN : "1HVBBAANXWH544237", LicensePlateNumber : "LS477D", State : "WA", City : "Tacoma", PendingPenaltyTicketAmount : new Decimal(4220, -2), ValidFromDate : new Date("2011-10-26"), ValidToDate : new Date("2023-09-25"), Owners : { PrimaryOwner : { PersonId : "" }, SecondaryOwners : EMPTY_SECONDARY_OWNERS } }, { VIN : "1C4RJFAG0FC625797", LicensePlateNumber : "TH393F", State : "WA", City : "Olympia", PendingPenaltyTicketAmount : new Decimal(3045, -2), ValidFromDate : new Date("2013-09-02"), ValidToDate : new Date("2024-03-19"), Owners : { PrimaryOwner : { PersonId : "" }, SecondaryOwners : EMPTY_SECONDARY_OWNERS } } ];
    2. Util.ts - 从 ion-js 包导入的实用程序模块,提供用于转换、解析和打印 Amazon Ion 数据的辅助函数。

      /* * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: MIT-0 * * Permission is hereby granted, free of charge, to any person obtaining a copy of this * software and associated documentation files (the "Software"), to deal in the Software * without restriction, including without limitation the rights to use, copy, modify, * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ import { Result, TransactionExecutor } from "amazon-qldb-driver-nodejs"; import { GetBlockResponse, GetDigestResponse, ValueHolder } from "aws-sdk/clients/qldb"; import { Decimal, decodeUtf8, dom, IonTypes, makePrettyWriter, makeReader, Reader, Timestamp, toBase64, Writer } from "ion-js"; import { error } from "./LogUtil"; /** * TODO: Replace this with json.stringify * Returns the string representation of a given BlockResponse. * @param blockResponse The BlockResponse to convert to string. * @returns The string representation of the supplied BlockResponse. */ export function blockResponseToString(blockResponse: GetBlockResponse): string { let stringBuilder: string = ""; if (blockResponse.Block.IonText) { stringBuilder = stringBuilder + "Block: " + blockResponse.Block.IonText + ", "; } if (blockResponse.Proof.IonText) { stringBuilder = stringBuilder + "Proof: " + blockResponse.Proof.IonText; } stringBuilder = "{" + stringBuilder + "}"; const writer: Writer = makePrettyWriter(); const reader: Reader = makeReader(stringBuilder); writer.writeValues(reader); return decodeUtf8(writer.getBytes()); } /** * TODO: Replace this with json.stringify * Returns the string representation of a given GetDigestResponse. * @param digestResponse The GetDigestResponse to convert to string. * @returns The string representation of the supplied GetDigestResponse. */ export function digestResponseToString(digestResponse: GetDigestResponse): string { let stringBuilder: string = ""; if (digestResponse.Digest) { stringBuilder += "Digest: " + JSON.stringify(toBase64(<Uint8Array> digestResponse.Digest)) + ", "; } if (digestResponse.DigestTipAddress.IonText) { stringBuilder += "DigestTipAddress: " + digestResponse.DigestTipAddress.IonText; } stringBuilder = "{" + stringBuilder + "}"; const writer: Writer = makePrettyWriter(); const reader: Reader = makeReader(stringBuilder); writer.writeValues(reader); return decodeUtf8(writer.getBytes()); } /** * Get the document IDs from the given table. * @param txn The {@linkcode TransactionExecutor} for lambda execute. * @param tableName The table name to query. * @param field A field to query. * @param value The key of the given field. * @returns Promise which fulfills with the document ID as a string. */ export async function getDocumentId( txn: TransactionExecutor, tableName: string, field: string, value: string ): Promise<string> { const query: string = `SELECT id FROM ${tableName} AS t BY id WHERE t.${field} = ?`; let documentId: string = undefined; await txn.execute(query, value).then((result: Result) => { const resultList: dom.Value[] = result.getResultList(); if (resultList.length === 0) { throw new Error(`Unable to retrieve document ID using ${value}.`); } documentId = resultList[0].get("id").stringValue(); }).catch((err: any) => { error(`Error getting documentId: ${err}`); }); return documentId; } /** * Sleep for the specified amount of time. * @param ms The amount of time to sleep in milliseconds. * @returns Promise which fulfills with void. */ export function sleep(ms: number): Promise<void> { return new Promise(resolve => setTimeout(resolve, ms)); } /** * Find the value of a given path in an Ion value. The path should contain a blob value. * @param value The Ion value that contains the journal block attributes. * @param path The path to a certain attribute. * @returns Uint8Array value of the blob, or null if the attribute cannot be found in the Ion value * or is not of type Blob */ export function getBlobValue(value: dom.Value, path: string): Uint8Array | null { const attribute: dom.Value = value.get(path); if (attribute !== null && attribute.getType() === IonTypes.BLOB) { return attribute.uInt8ArrayValue(); } return null; } /** * TODO: Replace this with json.stringify * Returns the string representation of a given ValueHolder. * @param valueHolder The ValueHolder to convert to string. * @returns The string representation of the supplied ValueHolder. */ export function valueHolderToString(valueHolder: ValueHolder): string { const stringBuilder: string = `{ IonText: ${valueHolder.IonText}}`; const writer: Writer = makePrettyWriter(); const reader: Reader = makeReader(stringBuilder); writer.writeValues(reader); return decodeUtf8(writer.getBytes()); } /** * Converts a given value to Ion using the provided writer. * @param value The value to convert to Ion. * @param ionWriter The Writer to pass the value into. * @throws Error: If the given value cannot be converted to Ion. */ export function writeValueAsIon(value: any, ionWriter: Writer): void { switch (typeof value) { case "string": ionWriter.writeString(value); break; case "boolean": ionWriter.writeBoolean(value); break; case "number": ionWriter.writeInt(value); break; case "object": if (Array.isArray(value)) { // Object is an array. ionWriter.stepIn(IonTypes.LIST); for (const element of value) { writeValueAsIon(element, ionWriter); } ionWriter.stepOut(); } else if (value instanceof Date) { // Object is a Date. ionWriter.writeTimestamp(Timestamp.parse(value.toISOString())); } else if (value instanceof Decimal) { // Object is a Decimal. ionWriter.writeDecimal(value); } else if (value === null) { ionWriter.writeNull(IonTypes.NULL); } else { // Object is a struct. ionWriter.stepIn(IonTypes.STRUCT); for (const key of Object.keys(value)) { ionWriter.writeFieldName(key); writeValueAsIon(value[key], ionWriter); } ionWriter.stepOut(); } break; default: throw new Error(`Cannot convert to Ion for type: ${(typeof value)}.`); } }
      注意

      getDocumentId函数运行一个查询,IDs从表中返回系统分配的文档。要了解更多信息,请参阅通过 BY 子句查询文档 ID

  2. 使用以下程序(InsertDocument.ts),将示例数据插入表内。

    /* * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: MIT-0 * * Permission is hereby granted, free of charge, to any person obtaining a copy of this * software and associated documentation files (the "Software"), to deal in the Software * without restriction, including without limitation the rights to use, copy, modify, * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ import { QldbDriver, Result, TransactionExecutor } from "amazon-qldb-driver-nodejs"; import { dom } from "ion-js"; import { getQldbDriver } from "./ConnectToLedger"; import { DRIVERS_LICENSE, PERSON, VEHICLE, VEHICLE_REGISTRATION } from "./model/SampleData"; import { DRIVERS_LICENSE_TABLE_NAME, PERSON_TABLE_NAME, VEHICLE_REGISTRATION_TABLE_NAME, VEHICLE_TABLE_NAME } from "./qldb/Constants"; import { error, log } from "./qldb/LogUtil"; /** * Insert the given list of documents into a table in a single transaction. * @param txn The {@linkcode TransactionExecutor} for lambda execute. * @param tableName Name of the table to insert documents into. * @param documents List of documents to insert. * @returns Promise which fulfills with a {@linkcode Result} object. */ export async function insertDocument( txn: TransactionExecutor, tableName: string, documents: object[] ): Promise<Result> { const statement: string = `INSERT INTO ${tableName} ?`; const result: Result = await txn.execute(statement, documents); return result; } /** * Handle the insertion of documents and updating PersonIds all in a single transaction. * @param txn The {@linkcode TransactionExecutor} for lambda execute. * @returns Promise which fulfills with void. */ async function updateAndInsertDocuments(txn: TransactionExecutor): Promise<void> { log("Inserting multiple documents into the 'Person' table..."); const documentIds: Result = await insertDocument(txn, PERSON_TABLE_NAME, PERSON); const listOfDocumentIds: dom.Value[] = documentIds.getResultList(); log("Updating PersonIds for 'DriversLicense' and PrimaryOwner for 'VehicleRegistration'..."); updatePersonId(listOfDocumentIds); log("Inserting multiple documents into the remaining tables..."); await Promise.all([ insertDocument(txn, DRIVERS_LICENSE_TABLE_NAME, DRIVERS_LICENSE), insertDocument(txn, VEHICLE_REGISTRATION_TABLE_NAME, VEHICLE_REGISTRATION), insertDocument(txn, VEHICLE_TABLE_NAME, VEHICLE) ]); } /** * Update the PersonId value for DriversLicense records and the PrimaryOwner value for VehicleRegistration records. * @param documentIds List of document IDs. */ export function updatePersonId(documentIds: dom.Value[]): void { documentIds.forEach((value: dom.Value, i: number) => { const documentId: string = value.get("documentId").stringValue(); DRIVERS_LICENSE[i].PersonId = documentId; VEHICLE_REGISTRATION[i].Owners.PrimaryOwner.PersonId = documentId; }); } /** * Insert documents into a table in a QLDB ledger. * @returns Promise which fulfills with void. */ const main = async function(): Promise<void> { try { const qldbDriver: QldbDriver = getQldbDriver(); await qldbDriver.executeLambda(async (txn: TransactionExecutor) => { await updateAndInsertDocuments(txn); }); } catch (e) { error(`Unable to insert documents: ${e}`); } } if (require.main === module) { main(); }
    注意
    • 该程序演示如何使用参数化值调用execute方法。除了要运行的 PartiQL 语句之外,您还可以传递数据参数。在语句字符串中将问号(?)作为变量占位符。

    • 如果 INSERT 语句成功,则返回每个插入文档的id

  3. 要运行编译后的程序,请输入以下命令。

    node dist/InsertDocument.js

接下来,您可以使用 SELECT 语句从 vehicle-registration 分类账中的表中读取数据。继续执行步骤 4:查询分类账中的表