

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

# Go 用 Amazon QLDB ドライバー — クイックスタートチュートリアル
<a name="driver-quickstart-golang"></a>

**重要**  
サポート終了通知: 既存のお客様は、07/31/2025 のサポート終了まで Amazon QLDB を使用できます。詳細については、[「Amazon QLDB 台帳を Amazon Aurora PostgreSQL に移行する](https://aws.amazon.com/blogs/database/migrate-an-amazon-qldb-ledger-to-amazon-aurora-postgresql/)」を参照してください。

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

**Topics**
+ [前提条件](#driver-quickstart-golang.prereqs)
+ [ステップ 1: ドライバーをインストールする](#driver-quickstart-golang.install)
+ [ステップ 2: パッケージをインポートする](#driver-quickstart-golang.import)
+ [ステップ 3: ドライバーを初期化する](#driver-quickstart-golang.initialize)
+ [ステップ 4: テーブルとインデックスを作成する](#driver-quickstart-golang.create-table-index)
+ [ステップ 5: ドキュメントを挿入する](#driver-quickstart-golang.insert)
+ [ステップ 6: クエリを実行してドキュメントを取得する](#driver-quickstart-golang.query)
+ [ステップ 7: ドキュメントを更新する](#driver-quickstart-golang.update)
+ [ステップ 8: クエリを実行して更新済みドキュメントを取得する](#driver-quickstart-golang.query-2)
+ [ステップ 9: テーブルを削除する](#driver-quickstart-golang.drop-table)
+ [完全なアプリケーションの実行](#driver-quickstart-golang.complete)

## 前提条件
<a name="driver-quickstart-golang.prereqs"></a>

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

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

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

   台帳の作成方法については、「[Amazon QLDB 台帳の基本的なオペレーション](ledger-management.basics.md)」、または「**コンソールの開始方法」の「[ステップ 1: 新しい台帳を作成する](getting-started-step-1.md)」を参照してください。

## ステップ 1: ドライバーをインストールする
<a name="driver-quickstart-golang.install"></a>

プロジェクトの依存関係をインストールする [Go モジュール](https://blog.golang.org/using-go-modules)をプロジェクトで使用していることを確認します。

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

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

ドライバーをインストールすると、[AWS SDK for Go v2](https://github.com/aws/aws-sdk-go-v2) パッケージや [Amazon Ion](https://github.com/amzn/ion-go) パッケージなどの依存関係もインストールされます。

## ステップ 2: パッケージをインポートする
<a name="driver-quickstart-golang.import"></a>

次の 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: ドライバーを初期化する
<a name="driver-quickstart-golang.initialize"></a>

`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: テーブルとインデックスを作成する
<a name="driver-quickstart-golang.create-table-index"></a>

以下のコード例は、`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)](concurrency.md) 競合例外を制限するために、[インデックス](ql-reference.create-index.md)が必要です。

## ステップ 5: ドキュメントを挿入する
<a name="driver-quickstart-golang.insert"></a>

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

### リテラル PartiQL の使用
<a name="driver-quickstart-golang.insert.partiql"></a>

次のコードでは、文字列のリテラル 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 データ型の使用
<a name="driver-quickstart-golang.insert.ion"></a>

Go の組み込み [JSON パッケージ](https://golang.org/pkg/encoding/json/)と同様に、Ion との間で Go データ型のマーシャルとアンマーシャルを行えます。

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

   ```
   type Person struct {
       FirstName string `ion:"firstName"`
       LastName  string `ion:"lastName"`
       Age       int    `ion:"age"`
   }
   ```

1. `Person` のインスタンスを作成します。

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

   ドライバーによって、Ion エンコードされた、`person` のテキスト表現がマーシャルされます。
**重要**  
マーシャルとアンマーシャルを適切に機能させるには、Go データ構造体のフィールド名をエクスポートする必要があります (先頭文字は大文字で表記)。

1. その `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](ql-reference.insert.md) ステートメントを使用して複数のドキュメントを挿入するために、次のように型 [list](driver-working-with-ion.md#driver-ion-list) のパラメータをステートメントに渡すことができます。  

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

## ステップ 6: クエリを実行してドキュメントを取得する
<a name="driver-quickstart-golang.query"></a>

次のコード例は、`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: ドキュメントを更新する
<a name="driver-quickstart-golang.update"></a>

次のコード例は、`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: クエリを実行して更新済みドキュメントを取得する
<a name="driver-quickstart-golang.query-2"></a>

次のコード例では、`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: テーブルを削除する
<a name="driver-quickstart-golang.drop-table"></a>

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

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

## 完全なアプリケーションの実行
<a name="driver-quickstart-golang.complete"></a>

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

**注記**  
このコードを実行する前に、`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)
    }
}
```