Ruby の Hello World

このコードサンプルは、Ruby で動作する「Hello World」アプリケーションです。このサンプルでは、次のタスクを行う方法を説明します。

  • 認証を設定する
  • Bigtable インスタンスに接続する
  • 新しいテーブルを作成する
  • テーブルにデータを書き込む
  • そのデータを読み取る
  • テーブルを削除する

認証を設定する

ローカル開発環境でこのページの Ruby サンプルを使用するには、gcloud CLI をインストールして初期化し、ユーザー認証情報を使用してアプリケーションのデフォルト認証情報を設定します。

  1. Install the Google Cloud CLI.

  2. If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.

  3. To initialize the gcloud CLI, run the following command:

    gcloud init
  4. If you're using a local shell, then create local authentication credentials for your user account:

    gcloud auth application-default login

    You don't need to do this if you're using Cloud Shell.

    If an authentication error is returned, and you are using an external identity provider (IdP), confirm that you have signed in to the gcloud CLI with your federated identity.

詳細については Set up authentication for a local development environment をご覧ください。

サンプルの実行

このコードサンプルでは、Ruby 用 Google Cloud クライアント ライブラリBigtable 用 Ruby クライアント ライブラリ パッケージを使用して Bigtable と通信します。

このサンプル プログラムを実行するには、GitHub でのサンプルの手順に沿って操作してください。

Bigtable での Cloud クライアント ライブラリの使用

このサンプル アプリケーションは Bigtable に接続して、いくつかの単純なオペレーションを行います。

必要なクライアント ライブラリ

このサンプルでは、Bigtable モジュールを提供する google/cloud/bigtable が必要です。

require "google/cloud/bigtable"

Bigtable への接続

"YOUR_PROJECT_ID" を有効な Google Cloud プロジェクトの ID に置き換えて、アプリケーションで使用する変数を設定します。次に、Bigtable に接続するために使用する Bigtable オブジェクトを新規作成します。

# These variables are used in the sample code below.
# instance_id      = "my-instance"
# table_id         = "my-table"
# column_family    = "cf"
# column_qualifier = "greeting"

bigtable = Google::Cloud::Bigtable.new
table_client = bigtable.table_admin_client

テーブルの作成

テーブルがすでに存在するかどうかを確認します。存在しない場合は、create_table() メソッドを呼び出して Table オブジェクトを作成します。このテーブルには、各値の 1 つのバージョンを保持する単一の列ファミリーがあります。

# This is the full resource name for the table. Use this name to make admin
# calls for the table, such as reading or deleting the resource.
table_name = table_client.table_path project: bigtable.project_id,
                                     instance: instance_id,
                                     table: table_id
begin
  # Attempt to get the table to see if it already exists
  table_client.get_table name: table_name
  puts "#{table_id} is already exists."
  exit 0
rescue Google::Cloud::NotFoundError
  # The table doesn't exist, so let's create it.
  # The following is the resource name for the table's instance.
  instance_name = table_client.instance_path project: bigtable.project_id,
                                             instance: instance_id
  # This is the configuration of the table's column families.
  table_config = {
    column_families: {
      column_family => {
        gc_rule: Google::Cloud::Bigtable::Admin::V2::GcRule.max_num_versions(1)
      }
    }
  }
  # Now call the API to create the table.
  table_client.create_table parent: instance_name,
                            table_id: table_id,
                            table: table_config
  puts "Table #{table_id} created."
end

テーブルへの行の書き込み

次に、グリーティングの文字列配列を使用してテーブルの新しい行を作成します。グリーティングごとに、テーブルの new_mutation_entry() メソッドを使用してエントリを作成します。次に、エントリの set_cell() メソッドを使用して、列ファミリー、列修飾子、グリーティング、タイムスタンプをエントリに割り当てます。最後に、テーブルの mutate_row() メソッドを使用してテーブルにエントリを書き込みます。

puts "Write some greetings to the table #{table_id}"
greetings = ["Hello World!", "Hello Bigtable!", "Hello Ruby!"]

# Get a table data object for the new table we created.
table = bigtable.table instance_id, table_id

# Insert rows one by one
# Note: To perform multiple mutation on multiple rows use `mutate_rows`.
greetings.each_with_index do |value, i|
  puts " Writing,  Row key: greeting#{i}, Value: #{value}"

  entry = table.new_mutation_entry "greeting#{i}"
  entry.set_cell(
    column_family,
    column_qualifier,
    value,
    timestamp: (Time.now.to_f * 1_000_000).round(-3)
  )

  table.mutate_row entry
end

フィルタの作成

書き込んだデータを読み取る前に、Bigtable によって返されるデータを制限するためのフィルタを作成します。このフィルタは、ガベージ コレクションが行われていない古いバージョンがテーブルに含まれていても、各値の最新バージョンのみを返すように Bigtable に指示します。

# Only retrieve the most recent version of the cell.
filter = Google::Cloud::Bigtable::RowFilter.cells_per_column 1

行キーによる行の読み取り

行オブジェクトを作成し、read_row() メソッドを呼び出してフィルタを渡し、その行の各値の 1 つのバージョンを取得します。

puts "Reading a single row by row key"
row = table.read_row "greeting0", filter: filter
puts "Row key: #{row.key}, Value: #{row.cells[column_family].first.value}"

すべてのテーブル行のスキャン

テーブル内のすべての行を取得するには、read_rows() メソッドを呼び出してフィルタを渡します。フィルタを渡しているため、Bigtable は各値の 1 つのバージョンのみを返します。

puts "Reading the entire table"
table.read_rows.each do |row|
  puts "Row key: #{row.key}, Value: #{row.cells[column_family].first.value}"
end

テーブルの削除

テーブルの delete() メソッドを使用してテーブルを削除します。

puts "Deleting the table #{table_id}"
# Call the admin API to delete the table given its full resource path.
table_client.delete_table name: table_name

すべてを組み合わせる

コメントなしの完全なコードサンプルを以下に示します。

# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

def hello_world instance_id, table_id, column_family, column_qualifier
  require "google/cloud/bigtable"

  # These variables are used in the sample code below.
  # instance_id      = "my-instance"
  # table_id         = "my-table"
  # column_family    = "cf"
  # column_qualifier = "greeting"

  bigtable = Google::Cloud::Bigtable.new
  table_client = bigtable.table_admin_client

  # This is the full resource name for the table. Use this name to make admin
  # calls for the table, such as reading or deleting the resource.
  table_name = table_client.table_path project: bigtable.project_id,
                                       instance: instance_id,
                                       table: table_id
  begin
    # Attempt to get the table to see if it already exists
    table_client.get_table name: table_name
    puts "#{table_id} is already exists."
    exit 0
  rescue Google::Cloud::NotFoundError
    # The table doesn't exist, so let's create it.
    # The following is the resource name for the table's instance.
    instance_name = table_client.instance_path project: bigtable.project_id,
                                               instance: instance_id
    # This is the configuration of the table's column families.
    table_config = {
      column_families: {
        column_family => {
          gc_rule: Google::Cloud::Bigtable::Admin::V2::GcRule.max_num_versions(1)
        }
      }
    }
    # Now call the API to create the table.
    table_client.create_table parent: instance_name,
                              table_id: table_id,
                              table: table_config
    puts "Table #{table_id} created."
  end

  puts "Write some greetings to the table #{table_id}"
  greetings = ["Hello World!", "Hello Bigtable!", "Hello Ruby!"]

  # Get a table data object for the new table we created.
  table = bigtable.table instance_id, table_id

  # Insert rows one by one
  # Note: To perform multiple mutation on multiple rows use `mutate_rows`.
  greetings.each_with_index do |value, i|
    puts " Writing,  Row key: greeting#{i}, Value: #{value}"

    entry = table.new_mutation_entry "greeting#{i}"
    entry.set_cell(
      column_family,
      column_qualifier,
      value,
      timestamp: (Time.now.to_f * 1_000_000).round(-3)
    )

    table.mutate_row entry
  end

  # Only retrieve the most recent version of the cell.
  filter = Google::Cloud::Bigtable::RowFilter.cells_per_column 1

  puts "Reading a single row by row key"
  row = table.read_row "greeting0", filter: filter
  puts "Row key: #{row.key}, Value: #{row.cells[column_family].first.value}"

  puts "Reading the entire table"
  table.read_rows.each do |row|
    puts "Row key: #{row.key}, Value: #{row.cells[column_family].first.value}"
  end

  puts "Deleting the table #{table_id}"
  # Call the admin API to delete the table given its full resource path.
  table_client.delete_table name: table_name
end