Amazon QLDB driver for Go: tutorial de inicio rápido - Base de datos Amazon Quantum Ledger (AmazonQLDB)

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

Amazon QLDB driver for Go: tutorial de inicio rápido

importante

Aviso de fin de soporte: los clientes actuales podrán usar Amazon QLDB hasta que finalice el soporte, el 31 de julio de 2025. Para obtener más información, consulte Migración de un Amazon QLDB Ledger a Amazon Aurora SQL Postgre.

En este tutorial, aprenderás a configurar una aplicación sencilla con la última versión del QLDB controlador Amazon para Go. Esta guía incluye los pasos para instalar el controlador y ejemplos breves de código de las operaciones básicas de creación, lectura, actualización y eliminación (CRUD).

Requisitos previos

Antes de comenzar, asegúrese de que hace lo siguiente:

  1. Si aún no lo ha hecho, complete el Requisitos previos para el controlador Go. Esto incluye registrarse AWS, conceder acceso programático para el desarrollo e instalar Go.

  2. Cree un libro mayor denominado quick-start.

    Para obtener más información sobre cómo crear un libro mayor, consulte Operaciones básicas para los libros de QLDB contabilidad de Amazon o Paso 1: crear un nuevo libro mayor en Introducción a la consola.

Paso 1: instalar el controlador

Asegúrese de que su proyecto utilice los módulos de Go para instalar las dependencias del proyecto.

Ejecute el siguiente comando go get en el directorio de su proyecto.

$ go get -u github.com/awslabs/amazon-qldb-driver-go/v3/qldbdriver

Al instalar el controlador también se instalan sus dependencias, incluidos AWS SDK for Go v2 y los paquetes de Amazon Ion.

Paso 2: importar los paquetes

Importa los siguientes AWS paquetes.

import ( "context" "fmt" "github.com/amzn/ion-go/ion" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/service/qldbSession" "github.com/awslabs/amazon-qldb-driver-go/v3/qldbdriver" )

Paso 3: inicializar el controlador

Inicialice una instancia del controlador que se conecte al libro mayor denominado quick-start.

cfg, err := config.LoadDefaultConfig(context.TODO()) if err != nil { panic(err) } qldbSession := qldbsession.NewFromConfig(cfg, func(options *qldbsession.Options) { options.Region = "us-east-1" }) driver, err := qldbdriver.New( "quick-start", qldbSession, func(options *qldbdriver.DriverOptions) { options.LoggerVerbosity = qldbdriver.LogInfo }) if err != nil { panic(err) } defer driver.Shutdown(context.Background())
nota

En este ejemplo de código, sustituya us-east-1 por el Región de AWS lugar donde creó su libro mayor.

Paso 4: crear una tabla y un índice

El siguiente ejemplo de código muestra cómo ejecutar las instrucciones CREATE TABLE y CREATE INDEX.

_, err = driver.Execute(context.Background(), func(txn qldbdriver.Transaction) (interface{}, error) { _, err := txn.Execute("CREATE TABLE People") if err != nil { return nil, err } // When working with QLDB, it's recommended to create an index on fields we're filtering on. // This reduces the chance of OCC conflict exceptions with large datasets. _, err = txn.Execute("CREATE INDEX ON People (firstName)") if err != nil { return nil, err } _, err = txn.Execute("CREATE INDEX ON People (age)") if err != nil { return nil, err } return nil, nil }) if err != nil { panic(err) }

Este código crea una tabla con el nombre People y los índices de los campos firstName y age de esa tabla. Los índices son necesarios para optimizar el rendimiento de las consultas y ayudar a limitar las excepciones optimistas en materia de control de simultaneidad (OCC) conflictos.

Paso 5: insertar un documento

El siguiente ejemplo de código muestra cómo ejecutar la instrucción INSERT. QLDBadmite el lenguaje de consultas PartiQL (SQLcompatible) y el formato de datos Amazon Ion (superconjunto de). JSON

Uso de literales PartiQL

El siguiente código inserta un documento en la tabla People mediante una instrucción PartiQL de literal de cadena.

_, err = driver.Execute(context.Background(), func(txn qldbdriver.Transaction) (interface{}, error) { return txn.Execute("INSERT INTO People {'firstName': 'Jane', 'lastName': 'Doe', 'age': 77}") }) if err != nil { panic(err) }

Uso de tipos de datos de Ion

Al igual que en el JSONpaquete integrado de Go, puede ordenar y desordenar los tipos de datos de Go desde y hacia Ion.

  1. Suponga que tiene la siguiente estructura de Go denominada Person.

    type Person struct { FirstName string `ion:"firstName"` LastName string `ion:"lastName"` Age int `ion:"age"` }
  2. Cree una instancia de Person.

    person := Person{"John", "Doe", 54}

    El controlador serializa automáticamente una representación de texto codificada en Ion de person.

    importante

    Para que la serialización y la anulación de la serialización funcionen correctamente, se deben exportar los nombres de campo de la estructura de datos de Go (primera letra en mayúscula).

  3. Pase la instancia person al método Execute de la transacción.

    _, err = driver.Execute(context.Background(), func(txn qldbdriver.Transaction) (interface{}, error) { return txn.Execute("INSERT INTO People ?", person) }) if err != nil { panic(err) }

    En este ejemplo se emplea un signo de interrogación (?) como marcador de posición variable para pasar la información del documento a la instrucción. Al utilizar marcadores de posición, debe pasar un valor de texto codificado por Ion.

    sugerencia

    Para insertar varios documentos mediante una sola instrucción INSERT, puede pasar un parámetro del tipo list a la instrucción de la siguiente manera.

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

    No coloque el marcador de posición variable (?) entre corchetes de doble ángulo (<<...>>) al pasar una lista. En las instrucciones PartiQL manuales, los corchetes de doble ángulo indican una colección desordenada conocida como bolsa.

Paso 6: consulta del documento

El siguiente ejemplo de código muestra cómo ejecutar una instrucción SELECT.

p, err := driver.Execute(context.Background(), func(txn qldbdriver.Transaction) (interface{}, error) { result, err := txn.Execute("SELECT firstName, lastName, age FROM People WHERE age = 54") if err != nil { return nil, err } // Assume the result is not empty hasNext := result.Next(txn) if !hasNext && result.Err() != nil { return nil, result.Err() } ionBinary := result.GetCurrentData() temp := new(Person) err = ion.Unmarshal(ionBinary, temp) if err != nil { return nil, err } return *temp, nil }) if err != nil { panic(err) } var returnedPerson Person returnedPerson = p.(Person) if returnedPerson != person { fmt.Print("Queried result does not match inserted struct") }

En este ejemplo, se consulta el documento desde la tabla People, se supone que el conjunto de resultados no está vacío y se devuelve el documento a partir del resultado.

Paso 7: actualizar el documento

El siguiente ejemplo de código muestra cómo ejecutar una instrucción UPDATE.

person.Age += 10 _, err = driver.Execute(context.Background(), func(txn qldbdriver.Transaction) (interface{}, error) { return txn.Execute("UPDATE People SET age = ? WHERE firstName = ?", person.Age, person.FirstName) }) if err != nil { panic(err) }

Paso 8: consulta al documento actualizado

El siguiente ejemplo de código consulta la tabla People mediante firstName y devuelve todos los documentos del conjunto de resultados.

p, err = driver.Execute(context.Background(), func(txn qldbdriver.Transaction) (interface{}, error) { result, err := txn.Execute("SELECT firstName, lastName, age FROM People WHERE firstName = ?", person.FirstName) if err != nil { return nil, err } var people []Person for result.Next(txn) { ionBinary := result.GetCurrentData() temp := new(Person) err = ion.Unmarshal(ionBinary, temp) if err != nil { return nil, err } people = append(people, *temp) } if result.Err() != nil { return nil, result.Err() } return people, nil }) if err != nil { panic(err) } var people []Person people = p.([]Person) updatedPerson := Person{"John", "Doe", 64} if people[0] != updatedPerson { fmt.Print("Queried result does not match updated struct") }

Paso 9: descarte de la tabla

El siguiente ejemplo de código muestra cómo ejecutar una instrucción DROP TABLE.

_, err = driver.Execute(context.Background(), func(txn qldbdriver.Transaction) (interface{}, error) { return txn.Execute("DROP TABLE People") }) if err != nil { panic(err) }

Ejecución de la aplicación completa

El siguiente ejemplo de código es la versión completa de la aplicación . En lugar de seguir los pasos anteriores de forma individual, también puede copiar y ejecutar este ejemplo de código de principio a fin. Esta aplicación muestra algunas CRUD operaciones básicas en el registro mencionado. quick-start

nota

Antes de ejecutar este código, asegúrese de no tener ya una tabla activa con el nombre People en el libro mayor quick-start.

package main import ( "context" "fmt" "github.com/amzn/ion-go/ion" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/qldbsession" "github.com/awslabs/amazon-qldb-driver-go/v2/qldbdriver" ) func main() { awsSession := session.Must(session.NewSession(aws.NewConfig().WithRegion("us-east-1"))) qldbSession := qldbsession.New(awsSession) driver, err := qldbdriver.New( "quick-start", qldbSession, func(options *qldbdriver.DriverOptions) { options.LoggerVerbosity = qldbdriver.LogInfo }) if err != nil { panic(err) } defer driver.Shutdown(context.Background()) _, err = driver.Execute(context.Background(), func(txn qldbdriver.Transaction) (interface{}, error) { _, err := txn.Execute("CREATE TABLE People") if err != nil { return nil, err } // When working with QLDB, it's recommended to create an index on fields we're filtering on. // This reduces the chance of OCC conflict exceptions with large datasets. _, err = txn.Execute("CREATE INDEX ON People (firstName)") if err != nil { return nil, err } _, err = txn.Execute("CREATE INDEX ON People (age)") if err != nil { return nil, err } return nil, nil }) if err != nil { panic(err) } _, err = driver.Execute(context.Background(), func(txn qldbdriver.Transaction) (interface{}, error) { return txn.Execute("INSERT INTO People {'firstName': 'Jane', 'lastName': 'Doe', 'age': 77}") }) if err != nil { panic(err) } type Person struct { FirstName string `ion:"firstName"` LastName string `ion:"lastName"` Age int `ion:"age"` } person := Person{"John", "Doe", 54} _, err = driver.Execute(context.Background(), func(txn qldbdriver.Transaction) (interface{}, error) { return txn.Execute("INSERT INTO People ?", person) }) if err != nil { panic(err) } p, err := driver.Execute(context.Background(), func(txn qldbdriver.Transaction) (interface{}, error) { result, err := txn.Execute("SELECT firstName, lastName, age FROM People WHERE age = 54") if err != nil { return nil, err } // Assume the result is not empty hasNext := result.Next(txn) if !hasNext && result.Err() != nil { return nil, result.Err() } ionBinary := result.GetCurrentData() temp := new(Person) err = ion.Unmarshal(ionBinary, temp) if err != nil { return nil, err } return *temp, nil }) if err != nil { panic(err) } var returnedPerson Person returnedPerson = p.(Person) if returnedPerson != person { fmt.Print("Queried result does not match inserted struct") } person.Age += 10 _, err = driver.Execute(context.Background(), func(txn qldbdriver.Transaction) (interface{}, error) { return txn.Execute("UPDATE People SET age = ? WHERE firstName = ?", person.Age, person.FirstName) }) if err != nil { panic(err) } p, err = driver.Execute(context.Background(), func(txn qldbdriver.Transaction) (interface{}, error) { result, err := txn.Execute("SELECT firstName, lastName, age FROM People WHERE firstName = ?", person.FirstName) if err != nil { return nil, err } var people []Person for result.Next(txn) { ionBinary := result.GetCurrentData() temp := new(Person) err = ion.Unmarshal(ionBinary, temp) if err != nil { return nil, err } people = append(people, *temp) } if result.Err() != nil { return nil, result.Err() } return people, nil }) if err != nil { panic(err) } var people []Person people = p.([]Person) updatedPerson := Person{"John", "Doe", 64} if people[0] != updatedPerson { fmt.Print("Queried result does not match updated struct") } _, err = driver.Execute(context.Background(), func(txn qldbdriver.Transaction) (interface{}, error) { return txn.Execute("DROP TABLE People") }) if err != nil { panic(err) } }