Beispiel: "Hello Word"-Anwendung in Go

Dieses Beispiel ist eine sehr einfache "Hello World"-Anwendung, geschrieben in Go, die veranschaulicht, wie:

  • eine Verbindung zu einer Cloud Bigtable-Instanz aufgebaut wird.
  • Erstellen einer neuen Tabelle
  • Schreiben von Daten in die Tabelle
  • Lesen von Daten aus der Tabelle
  • Löschen einer Tabelle

Beispiel ausführen

Dieses Beispiel nutzt das Cloud Bigtable-Paket der Google Cloud-Clientbibliothek für C++, um mit Bigtable zu kommunizieren.

Folgen Sie der Anleitung zum Beispiel auf GitHub, um das Beispielprogramm auszuführen.

Cloud-Clientbibliothek mit Bigtable verwenden

Die Beispielanwendung stellt eine Verbindung zu Bigtable her und zeigt einige einfache Vorgänge.

Clientbibliothek importieren

Das Beispiel nutzt die folgenden Importe:

import (
	"context"
	"flag"
	"fmt"
	"log"

	"cloud.google.com/go/bigtable"
)

Verbindung zu Bigtable herstellen, um Tabellen zu verwalten

Zum Verwalten von Tabellen müssen Sie eine Verbindung zu Bigtable herstellen. Hierzu verwenden Sie bigtable.NewAdminClient().

adminClient, err := bigtable.NewAdminClient(ctx, *project, *instance)
if err != nil {
	log.Fatalf("Could not create admin client: %v", err)
}

Tabelle erstellen

Erstellen Sie eine Tabelle mit AdminClient.CreateTable() und rufen Sie dann mit AdminClient.TableInfo() Informationen zur Tabelle ab. Erstellen Sie mit AdminClient.CreateColumnFamily() eine Spaltenfamilie.

tables, err := adminClient.Tables(ctx)
if err != nil {
	log.Fatalf("Could not fetch table list: %v", err)
}

if !sliceContains(tables, tableName) {
	log.Printf("Creating table %s", tableName)
	if err := adminClient.CreateTable(ctx, tableName); err != nil {
		log.Fatalf("Could not create table %s: %v", tableName, err)
	}
}

tblInfo, err := adminClient.TableInfo(ctx, tableName)
if err != nil {
	log.Fatalf("Could not read info for table %s: %v", tableName, err)
}

if !sliceContains(tblInfo.Families, columnFamilyName) {
	if err := adminClient.CreateColumnFamily(ctx, tableName, columnFamilyName); err != nil {
		log.Fatalf("Could not create column family %s: %v", columnFamilyName, err)
	}
}

Mit Bigtable verbinden, um Daten zu verwalten

Zum Verwalten von Daten stellen Sie eine Verbindung zu Bigtable mit bigtable.NewClient() her.

client, err := bigtable.NewClient(ctx, *project, *instance)
if err != nil {
	log.Fatalf("Could not create data operations client: %v", err)
}

Zeilen in eine Tabelle schreiben

Öffnen Sie die Tabelle, die beschrieben werden soll. Verwenden Sie bigtable.NewMutation(), um eine Mutation für eine einzelne Zeile zu erstellen. Legen Sie dann mithilfe von Mutation.Set() Werte in der Zeile fest. Generieren Sie einen einzigartigen Zeilenschlüssel. Wiederholen Sie diese Schritte, um mehrere Mutationen zu erstellen. Verwenden Sie schließlich Table.ApplyBulk(), um alle Mutationen auf die Tabelle anzuwenden.

tbl := client.Open(tableName)
muts := make([]*bigtable.Mutation, len(greetings))
rowKeys := make([]string, len(greetings))

log.Printf("Writing greeting rows to table")
for i, greeting := range greetings {
	muts[i] = bigtable.NewMutation()
	muts[i].Set(columnFamilyName, columnName, bigtable.Now(), []byte(greeting))

	// Each row has a unique row key.
	//
	// Note: This example uses sequential numeric IDs for simplicity, but
	// this can result in poor performance in a production application.
	// Since rows are stored in sorted order by key, sequential keys can
	// result in poor distribution of operations across nodes.
	//
	// For more information about how to design a Bigtable schema for the
	// best performance, see the documentation:
	//
	//     https://cloud.google.com/bigtable/docs/schema-design
	rowKeys[i] = fmt.Sprintf("%s%d", columnName, i)
}

rowErrs, err := tbl.ApplyBulk(ctx, rowKeys, muts)
if err != nil {
	log.Fatalf("Could not apply bulk row mutation: %v", err)
}
if rowErrs != nil {
	for _, rowErr := range rowErrs {
		log.Printf("Error writing row: %v", rowErr)
	}
	log.Fatalf("Could not write some rows")
}

Zeile nach ihrem Schlüssel lesen

Rufen Sie eine Zeile direkt mit ihrem Schlüssel mit Table.ReadRow() ab.

log.Printf("Getting a single greeting by row key:")
row, err := tbl.ReadRow(ctx, rowKeys[0], bigtable.RowFilter(bigtable.ColumnFilter(columnName)))
if err != nil {
	log.Fatalf("Could not read row with key %s: %v", rowKeys[0], err)
}
log.Printf("\t%s = %s\n", rowKeys[0], string(row[columnFamilyName][0].Value))

Alle Tabellenzeilen scannen

Mit Table.ReadRows() scannen Sie alle Zeilen in einer Tabelle. Den Daten-Client schließen, wenn Sie mit der Nutzung fertig sind.

log.Printf("Reading all greeting rows:")
err = tbl.ReadRows(ctx, bigtable.PrefixRange(columnName), func(row bigtable.Row) bool {
	item := row[columnFamilyName][0]
	log.Printf("\t%s = %s\n", item.Row, string(item.Value))
	return true
}, bigtable.RowFilter(bigtable.ColumnFilter(columnName)))

if err = client.Close(); err != nil {
	log.Fatalf("Could not close data operations client: %v", err)
}

Tabelle löschen

Löschen Sie eine Tabelle mit AdminClient.DeleteTable(). Den Admin-Client schließen, wenn Sie mit der Nutzung fertig sind.

log.Printf("Deleting the table")
if err = adminClient.DeleteTable(ctx, tableName); err != nil {
	log.Fatalf("Could not delete table %s: %v", tableName, err)
}

if err = adminClient.Close(); err != nil {
	log.Fatalf("Could not close admin client: %v", err)
}

Zusammenfassung

Hier ist das gesamte Beispiel ohne Kommentare:


package main

import (
	"context"
	"flag"
	"fmt"
	"log"

	"cloud.google.com/go/bigtable"
)

const (
	tableName        = "Hello-Bigtable"
	columnFamilyName = "cf1"
	columnName       = "greeting"
)

var greetings = []string{"Hello World!", "Hello Cloud Bigtable!", "Hello golang!"}

func sliceContains(list []string, target string) bool {
	for _, s := range list {
		if s == target {
			return true
		}
	}
	return false
}

func main() {
	project := flag.String("project", "", "The Google Cloud Platform project ID. Required.")
	instance := flag.String("instance", "", "The Google Cloud Bigtable instance ID. Required.")
	flag.Parse()

	for _, f := range []string{"project", "instance"} {
		if flag.Lookup(f).Value.String() == "" {
			log.Fatalf("The %s flag is required.", f)
		}
	}

	ctx := context.Background()

	adminClient, err := bigtable.NewAdminClient(ctx, *project, *instance)
	if err != nil {
		log.Fatalf("Could not create admin client: %v", err)
	}

	tables, err := adminClient.Tables(ctx)
	if err != nil {
		log.Fatalf("Could not fetch table list: %v", err)
	}

	if !sliceContains(tables, tableName) {
		log.Printf("Creating table %s", tableName)
		if err := adminClient.CreateTable(ctx, tableName); err != nil {
			log.Fatalf("Could not create table %s: %v", tableName, err)
		}
	}

	tblInfo, err := adminClient.TableInfo(ctx, tableName)
	if err != nil {
		log.Fatalf("Could not read info for table %s: %v", tableName, err)
	}

	if !sliceContains(tblInfo.Families, columnFamilyName) {
		if err := adminClient.CreateColumnFamily(ctx, tableName, columnFamilyName); err != nil {
			log.Fatalf("Could not create column family %s: %v", columnFamilyName, err)
		}
	}

	client, err := bigtable.NewClient(ctx, *project, *instance)
	if err != nil {
		log.Fatalf("Could not create data operations client: %v", err)
	}

	tbl := client.Open(tableName)
	muts := make([]*bigtable.Mutation, len(greetings))
	rowKeys := make([]string, len(greetings))

	log.Printf("Writing greeting rows to table")
	for i, greeting := range greetings {
		muts[i] = bigtable.NewMutation()
		muts[i].Set(columnFamilyName, columnName, bigtable.Now(), []byte(greeting))

		rowKeys[i] = fmt.Sprintf("%s%d", columnName, i)
	}

	rowErrs, err := tbl.ApplyBulk(ctx, rowKeys, muts)
	if err != nil {
		log.Fatalf("Could not apply bulk row mutation: %v", err)
	}
	if rowErrs != nil {
		for _, rowErr := range rowErrs {
			log.Printf("Error writing row: %v", rowErr)
		}
		log.Fatalf("Could not write some rows")
	}

	log.Printf("Getting a single greeting by row key:")
	row, err := tbl.ReadRow(ctx, rowKeys[0], bigtable.RowFilter(bigtable.ColumnFilter(columnName)))
	if err != nil {
		log.Fatalf("Could not read row with key %s: %v", rowKeys[0], err)
	}
	log.Printf("\t%s = %s\n", rowKeys[0], string(row[columnFamilyName][0].Value))

	log.Printf("Reading all greeting rows:")
	err = tbl.ReadRows(ctx, bigtable.PrefixRange(columnName), func(row bigtable.Row) bool {
		item := row[columnFamilyName][0]
		log.Printf("\t%s = %s\n", item.Row, string(item.Value))
		return true
	}, bigtable.RowFilter(bigtable.ColumnFilter(columnName)))

	if err = client.Close(); err != nil {
		log.Fatalf("Could not close data operations client: %v", err)
	}

	log.Printf("Deleting the table")
	if err = adminClient.DeleteTable(ctx, tableName); err != nil {
		log.Fatalf("Could not delete table %s: %v", tableName, err)
	}

	if err = adminClient.Close(); err != nil {
		log.Fatalf("Could not close admin client: %v", err)
	}
}