Go 用 Amazon QLDBドライバー — クイックスタートチュートリアル - Amazon Quantum 台帳データベース (Amazon QLDB)

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

Go 用 Amazon QLDBドライバー — クイックスタートチュートリアル

重要

サポート終了通知: 既存のお客様は、07/31/2025 のサポート終了QLDBまで Amazon を使用できます。詳細については、「Amazon Ledger QLDB を Amazon Aurora Postgre に移行するSQL」を参照してください。

このチュートリアルでは、Go 用 Amazon QLDBドライバーの最新バージョンを使用してシンプルなアプリケーションを設定する方法について説明します。このガイドには、ドライバーのインストール手順と、基本的な作成、読み取り、更新、削除 (CRUD) オペレーションの短いコード例が含まれています。

前提条件

作業を始める前に、次の操作を実行してください。

  1. Go ドライバー用の「前提条件」を完了します (まだ完了していない場合)。これには、 へのサインアップ AWS、開発用のプログラムによるアクセスの付与、Go のインストールが含まれます。

  2. quick-start という名前の台帳を作成します。

    台帳の作成方法については、「Amazon QLDB台帳の基本オペレーション」、または「コンソールの開始方法」の「ステップ 1: 新しい台帳を作成する」を参照してください。

ステップ 1: ドライバーをインストールする

プロジェクトの依存関係をインストールする Go モジュールをプロジェクトで使用していることを確認します。

プロジェクトディレクトリで次の go get コマンドを入力します。

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

ドライバーをインストールすると、AWS SDK for Go v2 パッケージや Amazon Ion パッケージなどの依存関係もインストールされます。

ステップ 2: パッケージをインポートする

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

ステップ 3: ドライバーを初期化する

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())
注記

このコード例では、us-east-1 台帳を作成した AWS リージョン を使用します。

ステップ 4: テーブルとインデックスを作成する

以下のコード例は、CREATE TABLE および 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) }

このコードにより、People という名前のテーブルと、そのテーブルにある firstName フィールドと age フィールドのインデックスが作成されます。インデックスは、クエリのパフォーマンスを最適化し、オプティミスティック同時実行制御 (OCC) の競合例外を制限するのに役立ちます。

ステップ 5: ドキュメントを挿入する

次のコード例は、INSERT ステートメントの実行方法を示しています。QLDB は、PartiQLクエリ言語 (SQL互換) と Amazon Ion データ形式 ( のスーパーセット) をサポートしていますJSON。

リテラル PartiQL の使用

次のコードでは、文字列のリテラル PartiQL ステートメントを使用して、People テーブルにドキュメントを挿入しています。

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

Ion データ型の使用

Go の組み込みJSONパッケージ と同様に、Ion との間で Go データ型をマーシャリングおよびアンマーシャリングできます。

  1. Person という名前を持つ次のような Go 構造体があるとします。

    type Person struct { FirstName string `ion:"firstName"` LastName string `ion:"lastName"` Age int `ion:"age"` }
  2. Person のインスタンスを作成します。

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

    ドライバーによって、Ion エンコードされた、person のテキスト表現がマーシャルされます。

    重要

    マーシャルとアンマーシャルを適切に機能させるには、Go データ構造体のフィールド名をエクスポートする必要があります (先頭文字は大文字で表記)。

  3. その person インスタンスをトランザクションの Execute メソッドに渡します。

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

    この例では、疑問符 (?) を変数プレースホルダーとして使用して、ドキュメント情報をステートメントに渡します。プレースホルダーを使用する場合、Ion エンコードされたテキスト値を渡す必要があります。

    ヒント

    1 つの INSERT ステートメントを使用して複数のドキュメントを挿入するために、次のように型 list のパラメータをステートメントに渡すことができます。

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

    リストを渡すときには、変数プレースホルダー (?) を二重山括弧 (<<...>>) で囲まないでください。マニュアルの PartiQL ステートメントでは、二重山括弧はバッグと呼ばれる順序付けされていないコレクションを表します。

ステップ 6: クエリを実行してドキュメントを取得する

次のコード例は、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") }

この例では、People テーブルからドキュメントを取得するクエリが実行 (結果セットは空でないと仮定) され、その結果からドキュメントが返ります。

ステップ 7: ドキュメントを更新する

次のコード例は、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) }

ステップ 8: クエリを実行して更新済みドキュメントを取得する

次のコード例では、People テーブルに、firstName を使用してクエリが実行され、結果セット内のすべてのドキュメントが返ります。

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

ステップ 9: テーブルを削除する

次のコード例は、DROP TABLE ステートメントの実行方法を示しています。

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

完全なアプリケーションの実行

以下のコード例は、 アプリケーションの完全なバージョンです。上のステップを個別に実行する代わりに、このコード例を最初から最後までコピーして実行することもできます。このアプリケーションは、 という名前の台帳に対するいくつかの基本的なCRUDオペレーションを示していますquick-start

注記

このコードを実行する前に、quick-start 台帳に People という名前のアクティブなテーブルが存在しないことを確認してください。

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