Ruby hello world

דוגמת הקוד הזו היא אפליקציית Hello World שפועלת ב-Ruby. בדוגמה הזו מוסבר איך לבצע את הפעולות הבאות:

  • מגדירים אימות
  • מתחברים למכונה של Bigtable.
  • ליצור טבלה חדשה.
  • כתיבת נתונים בטבלה.
  • קוראים את הנתונים בחזרה.
  • מוחקים את הטבלה.

מגדירים אימות

כדי להשתמש בדוגמאות של Ruby שבדף הזה בסביבת פיתוח מקומית, מתקינים ומפעילים את ה-CLI של gcloud, ואז מגדירים את Application Default Credentials באמצעות פרטי הכניסה של המשתמש.

  1. התקינו את ה-CLI של Google Cloud.

  2. אם אתם משתמשים בספק זהויות חיצוני (IdP), קודם אתם צריכים להיכנס ל-CLI של gcloud באמצעות המאגר המאוחד לניהול זהויות.

  3. אם אתם משתמשים במעטפת מקומית, אתם צריכים ליצור פרטי כניסה לאימות מקומי עבור חשבון המשתמש:

    gcloud auth application-default login

    אם אתם משתמשים ב-Cloud Shell, אין צורך לבצע את הפעולה הזו.

    אם מוחזרת שגיאת אימות ואתם משתמשים בספק זהויות חיצוני (IdP), ודאו ש נכנסתם ל-CLI של gcloud באמצעות המאגר המאוחד לניהול זהויות.

מידע נוסף זמין במאמר הגדרת אימות לסביבת פיתוח מקומית.

הגדרת הסביבה

כדי להריץ את הדוגמה הזו, צריך להתקין את Ruby.

1. התקנת Ruby

כדי לבדוק את גרסת Ruby המינימלית הנדרשת לספריית הלקוח, אפשר לעיין ב-required_ruby_version בקובץ google-cloud-bigtable.gemspec.

הגדרה של Ruby במכונה וירטואלית ב-Compute Engine אם רוצים להריץ את הדוגמה במכונה וירטואלית ב-Compute Engine, צריך לפעול לפי ההוראות האלה כדי להגדיר את Ruby במכונה וירטואלית של Debian או Ubuntu.

  1. נכנסים לדף VM instances במסוף Google Cloud .

    כניסה לדף VM instances

  2. אם אין לכם מכונה וירטואלית (VM) של Linux שמשתמשת במערכת ההפעלה Debian או Ubuntu, צריך ליצור אחת ולהתחבר אליה. מידע נוסף זמין במאמר מדריך למתחילים: שימוש במכונה וירטואלית של Linux.

  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
    

מידע נוסף על ספריית הלקוח זמין בקובץ ה-README של google-cloud-bigtable.

הרצת הדוגמה

בדוגמת הקוד הזו נעשה שימוש בספריית הלקוח Ruby client library for Bigtable של Google Cloud Client Library for Ruby כדי לתקשר עם Bigtable.

כדי להריץ את תוכנית הדוגמה הזו, פועלים לפי ההוראות לדוגמה ב-GitHub.

שימוש בספריית הלקוח של Cloud עם Bigtable

אפליקציית הדוגמה מתחברת ל-Bigtable ומדגימה כמה פעולות פשוטות.

הוספת דרישה לספריית הלקוח

הדוגמה מחייבת את google/cloud/bigtable, שמספק את המודול Bigtable.

require "google/cloud/bigtable"

התחברות ל-Bigtable

מגדירים את המשתנים שבהם רוצים להשתמש באפליקציה, ומחליפים את YOUR_PROJECT_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

יצירת טבלה

בודקים אם הטבלה כבר קיימת. אם הוא לא קיים, צריך לבצע קריאה ל-method‏ 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

כתיבת שורות בטבלה

לאחר מכן, משתמשים במערך מחרוזות של ברכות כדי ליצור כמה שורות חדשות בטבלה. לכל ברכה, יוצרים רשומה באמצעות ה-method‏ 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}"

סריקה של כל השורות בטבלה

מבצעים קריאה ל-method‏ 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