Driver Amazon QLDB para Go — Tutorial de início rápido - Amazon Quantum Ledger Database (Amazon QLDB)

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

Driver Amazon QLDB para Go — Tutorial de início rápido

Neste tutorial, você aprenderá como configurar um aplicativo simples usando a versão mais recente do driver QLDB da Amazon para Go. Este guia inclui etapas para instalação do driver e exemplos de códigos curtos de operações básicas de criação, leitura, atualização e exclusão (CRUD).

Pré-requisitos

Antes de iniciar, certifique-se de fazer o seguinte:

  1. Complete a Pré-requisitos para o driver Go, caso ainda não o tenha feito. Isso inclui a inscrição em AWS, a concessão de acesso programático para desenvolvimento e a instalação do Go.

  2. Crie um ledger chamado quick-start.

    Para saber como criar um ledger, consulte Operações básicas para ledgers do Amazon QLDB ou Etapa 1: criar um novo ledger em Conceitos básicos do console.

Etapa 1: Instalar o driver

Certifique-se de que seu projeto esteja usando módulos Go para instalar as dependências do projeto.

No diretório do seu projeto, insira o seguinte comando go get.

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

A instalação do driver também instala suas dependências, incluindo os pacotes AWS SDK for Go v2 e Amazon Ion.

Etapa 2: Importar os pacotes

Importe os seguintes pacotes AWS.

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" )

Etapa 3: Inicializar o driver

Inicialize uma instância do driver que se conecta ao ledger chamado 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

Neste exemplo de código, substitua us-east-1 pelo Região da AWS em que você criou seu ledger.

Etapa 4: Crie uma tabela e um índice

O exemplo de código a seguir mostra como executar as instruções CREATE TABLE e 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) }

Esse código adiciona o código a seguir que cria uma tabela chamada People e índices para os campos firstName e age nessa tabela. Os índices são necessários para otimizar o desempenho da consulta e ajudar a limitar as exceções de conflitos de controle de simultaneidade otimista (OCC).

Etapa 5: Inserir um documento

Os exemplos de código a seguir mostram como executar uma instrução INSERT. O QLDB suporta a linguagem de consulta PartiQL (compatível com SQL) e o formato de dados Amazon Ion (superconjunto de JSON).

Uso do PartiQL literal

O código a seguir insere um documento na tabela People usando uma instrução partiQL literal de string.

_, 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 dados Ion

Semelhante ao pacote JSON integrado do Go, você pode organizar e desorganizar tipos de dados Go de e para o Ion.

  1. Suponha que você tenha a seguinte estrutura Go, chamada Person.

    type Person struct { FirstName string `ion:"firstName"` LastName string `ion:"lastName"` Age int `ion:"age"` }
  2. Crie uma instância de Person.

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

    O motorista organiza uma representação de person de texto codificada por Ion para você.

    Importante

    Para que a organização e desorganização funcionem corretamente, os nomes dos campos da estrutura de dados Go devem ser exportados (primeira letra maiúscula).

  3. Passe a instância person para o método Execute da transação.

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

    Este exemplo usa um ponto de interrogação (?) como um marcador variável para passar as informações do documento para a instrução. Ao usar marcadores, você deve passar um valor de texto codificado por Ion.

    dica

    Para inserir vários documentos usando uma única instrução INSERT, você pode passar um parâmetro do tipo lista para a instrução da seguinte maneira.

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

    Você não coloca o marcador variável (?) entre colchetes angulares duplos (<<...>>) ao passar uma lista. Nas instruções manuais do PartiQL, colchetes angulares duplos denotam uma coleção não ordenada conhecida como bolsa.

Etapa 6: consultar o documento

O exemplo de código a seguir mostra como executar uma SELECT instrução.

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") }

Este exemplo consulta seu documento a partir da tabela People, presume que o conjunto de resultados não está vazio e retorna seu documento a partir do resultado.

Etapa 7: Atualize o documento

O exemplo de código a seguir mostra como executar uma UPDATE instrução.

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) }

Etapa 8: consultar o documento atualizado

O exemplo de código a seguir consulta a tabela People por firstName e retorna todos os documentos no 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") }

Etapa 9: Descartar a tabela

O exemplo de código a seguir mostra como executar uma DROP TABLE instrução.

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

Executando o aplicativo completo

O exemplo de código a seguir é a versão completa do aplicativo . Em vez de executar as etapas anteriores individualmente, você também pode copiar e executar esse exemplo de código do início ao fim. Este aplicativo demonstra algumas operações básicas do CRUD no ledger denominado quick-start.

nota

Antes de executar esse código, verifique se você ainda não tem uma tabela ativa chamada People no quick-start ledger .

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) } }