Ruby hello world

這個程式碼範例是在 Ruby 上執行的「hello world」應用程式,示範如何完成下列工作:

  • 設定驗證方法
  • 連線至 Bigtable 執行個體。
  • 建立新的資料表。
  • 將資料寫入資料表。
  • 讀取資料。
  • 刪除資料表。

設定驗證方法

如要在本機開發環境中使用本頁的 Ruby 範例,請安裝並初始化 gcloud CLI,然後使用您的使用者憑證設定應用程式預設憑證。

  1. 安裝 Google Cloud CLI。

  2. 若您採用的是外部識別資訊提供者 (IdP),請先使用聯合身分登入 gcloud CLI

  3. 如果您使用本機殼層,請為使用者帳戶建立本機驗證憑證:

    gcloud auth application-default login

    如果您使用 Cloud Shell,則不需要執行這項操作。

    如果系統傳回驗證錯誤,且您使用外部識別資訊提供者 (IdP),請確認您已 使用聯合身分登入 gcloud CLI

詳情請參閱 這篇文章,瞭解如何設定本機開發環境的驗證機制。

設定環境

如要執行這個範例,您必須安裝 Ruby。

1. 安裝 Ruby

如要查看用戶端程式庫的最低 Ruby 版本需求,請參閱 google-cloud-bigtable.gemspec 檔案中的 required_ruby_version

在 Compute Engine VM 上設定 Ruby 如要在 Compute Engine VM 上執行範例,請按照這些指示在 Debian 或 Ubuntu VM 上設定 Ruby。

  1. 前往 Google Cloud 控制台的「VM instances」(VM 執行個體) 頁面

    前往 VM 執行個體

  2. 如果沒有使用 Debian 或 Ubuntu 作業系統的 Linux VM,請建立並連線至 VM。詳情請參閱「使用 Linux VM 的快速入門導覽課程」。

  3. 在 VM 的終端機視窗中,更新套件清單:

    sudo apt update
    
  4. 安裝 Ruby、Ruby 開發工具和 build-essential,這些是用戶端程式庫的必要項目:

    sudo apt install -y ruby ruby-dev build-essential
    
  5. 確認已安裝的 Ruby 版本符合 google-cloud-bigtable.gemspec 檔案中指定的最低需求:

    ruby --version
    

2. 安裝用戶端程式庫

如要安裝用戶端程式庫:

  1. 初始化 Bundler,在專案的根目錄中建立 Gemfile

    bundle init
    
  2. google-cloud-bigtable 新增至 Gemfile 並安裝:

    bundle add google-cloud-bigtable
    

如要進一步瞭解用戶端程式庫,請參閱 google-cloud-bigtable README

執行範例

本程式碼範例使用 Ruby 適用的 Google Cloud 用戶端程式庫Bigtable Ruby 用戶端程式庫套件,與 Bigtable 進行通訊。

如要執行這個範例程式,請按照 GitHub 網頁上的說明操作。

搭配 Cloud 用戶端程式庫使用 Bigtable

這個應用程式範例會連線至 Bigtable,示範部分簡易作業。

須使用用戶端程式庫

範例需要 google/cloud/bigtable,其中提供 Bigtable 模組。

require "google/cloud/bigtable"

連線至 Bigtable

建立要在應用程式中使用的變數,並將「YOUR_PROJECT_ID」替換為有效專案的 ID。 Google Cloud 然後建立新的 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 物件。資料表有單一資料欄系列,會保留每個值的一個版本。

# 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() 方法並傳入篩選器,即可取得該資料列中每個資料值的一個版本。

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 只會傳回每個值的一個版本。

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