Introdução ao Spanner em Ruby


Objetivos

Neste tutorial, mostramos as seguintes etapas usando o Spanner biblioteca de cliente para Ruby:

  • Criar uma instância e um banco de dados do Spanner.
  • Gravar, ler e executar consultas SQL em dados contidos no banco de dados.
  • Atualizar o esquema do banco de dados.
  • Atualizar dados usando uma transação de leitura e gravação.
  • Adicionar um índice secundário ao banco de dados.
  • Usar o índice para ler e executar consultas SQL nos dados.
  • Recuperar dados usando uma transação somente leitura.

Custos

Neste tutorial, usamos o Spanner, que é um componente faturável da Google Cloud. Para mais informações sobre o custo do uso do Spanner, consulte Preços.

Antes de começar

Conclua as etapas descritas em Configurar, que abrangem a criação e a configuração de um projeto padrão do Google Cloud, o faturamento, a API Cloud Spanner e a configuração do OAuth 2.0 para receber credenciais de autenticação para usar a API Cloud Spanner.

Especificamente, execute gcloud auth application-default login para configurar o ambiente de desenvolvimento local com credenciais de autenticação.

Preparar o ambiente Ruby local

  1. Instale os seguintes itens na sua máquina de desenvolvimento se ainda não estiverem instalados:

  2. Clone o repositório do aplicativo de amostra na máquina local:

    git clone https://github.com/GoogleCloudPlatform/ruby-docs-samples
    

    Outra opção é fazer o download da amostra como um arquivo zip e extraí-lo.

  3. Mude para o diretório que contém o código de exemplo do Spanner:

    cd ruby-docs-samples/spanner/
    
  4. Instale as dependências:

    bundle install
    
  5. Defina a variável de ambiente GOOGLE_CLOUD_PROJECT para seu Google Cloud ID do projeto:

    export GOOGLE_CLOUD_PROJECT=[MY_PROJECT_ID]
    

Criar uma instância

Quando você usa o Spanner pela primeira vez, precisa criar uma instância, que é um alocação de recursos usados pelos bancos de dados do Spanner. Ao criar uma instância, escolha uma configuração que determine onde os dados serão armazenados e também o número de nós a serem usados. Isso determina a quantidade de recursos de exibição e armazenamento na instância.

Execute o seguinte comando para criar uma instância do Spanner na região us-central1 com um nó:

gcloud spanner instances create test-instance --config=regional-us-central1 \
    --description="Test Instance" --nodes=1

A instância criada tem as seguintes características:

  • Código da instância: test-instance
  • Nome de exibição: Test Instance
  • Configuração da instância: regional-us-central1 as configurações regionais armazenam dados em uma região, enquanto as configurações multirregionais distribuem dados em várias regiões. Para mais informações, consulte Sobre instâncias.
  • Um nó node_count corresponde à quantidade de recursos de exibição e armazenamento disponíveis aos bancos de dados na instância. Saiba mais em Nós e unidades de processamento.

Você verá:

Creating instance...done.

Consultar os arquivos de amostra

O repositório de amostras contém um exemplo que mostra como usar o Spanner com Ruby.

Confira o arquivo spanner_samples.rb, que mostra como usar o Spanner. O código mostra como criar e usar um novo banco de dados. Os dados usam o esquema de exemplo exibido na página Esquema e modelo de dados.

Criar um banco de dados

Crie um banco de dados chamado example-db na instância denominada test-instance executando o seguinte na linha de comando.

bundle exec ruby spanner_samples.rb create_database test-instance example-db

Você verá:

Created database example-db on instance test-instance
O código a seguir cria um banco de dados e duas tabelas nele.
# project_id  = "Your Google Cloud project ID"
# instance_id = "Your Spanner instance ID"
# database_id = "Your Spanner database ID"

require "google/cloud/spanner"
require "google/cloud/spanner/admin/database"

database_admin_client = Google::Cloud::Spanner::Admin::Database.database_admin

instance_path = database_admin_client.instance_path project: project_id, instance: instance_id

job = database_admin_client.create_database parent: instance_path,
                                            create_statement: "CREATE DATABASE `#{database_id}`",
                                            extra_statements: [
                                              "CREATE TABLE Singers (
      SingerId     INT64 NOT NULL,
      FirstName    STRING(1024),
      LastName     STRING(1024),
      SingerInfo   BYTES(MAX)
    ) PRIMARY KEY (SingerId)",

                                              "CREATE TABLE Albums (
      SingerId     INT64 NOT NULL,
      AlbumId      INT64 NOT NULL,
      AlbumTitle   STRING(MAX)
    ) PRIMARY KEY (SingerId, AlbumId),
    INTERLEAVE IN PARENT Singers ON DELETE CASCADE"
                                            ]

puts "Waiting for create database operation to complete"

job.wait_until_done!

puts "Created database #{database_id} on instance #{instance_id}"

O próximo passo é gravar dados no seu banco de dados.

Criar um cliente de banco de dados

Antes de fazer leituras ou gravações, você deve criar um Client. Pense em um Client como uma conexão com o banco de dados: todas as suas interações com o Spanner precisam passar por um Client. Normalmente, você cria um Client quando seu aplicativo é iniciado, e depois reutiliza esse Client para ler, gravar e executar transações. O código a seguir mostra como criar um cliente.

# Imports the Google Cloud client library
require "google/cloud/spanner"

# Your Google Cloud Platform project ID
project_id = "YOUR_PROJECT_ID"

# Instantiates a client
spanner = Google::Cloud::Spanner.new project: project_id

# Your Cloud Spanner instance ID
instance_id = "my-instance"

# Your Cloud Spanner database ID
database_id = "my-database"

# Gets a reference to a Cloud Spanner instance database
database_client = spanner.client instance_id, database_id

# Execute a simple SQL statement
results = database_client.execute_query "SELECT 1"
results.rows.each do |row|
  puts row
end

Leia mais na referência de Client.

Gravar dados com DML

É possível inserir dados usando a linguagem de manipulação de dados (DML, na sigla em inglês) em uma transação de leitura/gravação.

Use o método execute_update() para executar uma instrução DML.

# project_id  = "Your Google Cloud project ID"
# instance_id = "Your Spanner instance ID"
# database_id = "Your Spanner database ID"

require "google/cloud/spanner"

spanner = Google::Cloud::Spanner.new project: project_id
client  = spanner.client instance_id, database_id
row_count = 0

client.transaction do |transaction|
  row_count = transaction.execute_update(
    "INSERT INTO Singers (SingerId, FirstName, LastName) VALUES
     (12, 'Melissa', 'Garcia'),
     (13, 'Russell', 'Morales'),
     (14, 'Jacqueline', 'Long'),
     (15, 'Dylan', 'Shaw'),
     (16, 'Billie', 'Eillish'),
     (17, 'Judy', 'Garland'),
     (18, 'Taylor', 'Swift'),
     (19, 'Miley', 'Cyrus'),
     (20, 'Michael', 'Jackson'),
     (21, 'Ariana', 'Grande'),
     (22, 'Elvis', 'Presley'),
     (23, 'Kanye', 'West'),
     (24, 'Lady', 'Gaga'),
     (25, 'Nick', 'Jonas')"
  )
end

puts "#{row_count} records inserted."

Execute a amostra usando o argumento write_using_dml.

bundle exec ruby spanner_samples.rb write_using_dml test-instance example-db

Você verá:

 4 records inserted.

Gravar dados com mutações

Também é possível inserir dados usando mutações.

Grave dados usando um objeto Client. O método Client#commit (em inglês) cria e confirma uma transação para gravações que são executadas atomicamente em um ponto lógico único no tempo em colunas, linhas e tabelas de um banco de dados.

Este código mostra como gravar dados usando mutações:

# project_id  = "Your Google Cloud project ID"
# instance_id = "Your Spanner instance ID"
# database_id = "Your Spanner database ID"

require "google/cloud/spanner"

spanner = Google::Cloud::Spanner.new project: project_id
client  = spanner.client instance_id, database_id

client.commit do |c|
  c.insert "Singers", [
    { SingerId: 1, FirstName: "Marc",     LastName: "Richards" },
    { SingerId: 2, FirstName: "Catalina", LastName: "Smith"    },
    { SingerId: 3, FirstName: "Alice",    LastName: "Trentor"  },
    { SingerId: 4, FirstName: "Lea",      LastName: "Martin"   },
    { SingerId: 5, FirstName: "David",    LastName: "Lomond"   }
  ]
  c.insert "Albums", [
    { SingerId: 1, AlbumId: 1, AlbumTitle: "Total Junk" },
    { SingerId: 1, AlbumId: 2, AlbumTitle: "Go, Go, Go" },
    { SingerId: 2, AlbumId: 1, AlbumTitle: "Green" },
    { SingerId: 2, AlbumId: 2, AlbumTitle: "Forever Hold Your Peace" },
    { SingerId: 2, AlbumId: 3, AlbumTitle: "Terrified" }
  ]
end

puts "Inserted data"

Execute a amostra usando o argumento insert_data.

bundle exec ruby spanner_samples.rb insert_data test-instance example-db

Você verá:

Inserted data

Consultar dados usando SQL

O Spanner oferece suporte a uma interface SQL para leitura de dados, que pode ser acessada na linha de comando usando a CLI do Google Cloud ou programaticamente usando a biblioteca de cliente do Spanner para Ruby.

Na linha de comando

Execute a instrução SQL a seguir para ler os valores de todas as colunas da tabela Albums:

gcloud spanner databases execute-sql example-db --instance=test-instance \
    --sql='SELECT SingerId, AlbumId, AlbumTitle FROM Albums'

O resultado será:

SingerId AlbumId AlbumTitle
1        1       Total Junk
1        2       Go, Go, Go
2        1       Green
2        2       Forever Hold Your Peace
2        3       Terrified

Usar a biblioteca de cliente do Spanner para Ruby

Além de executar uma instrução SQL na linha de comando, você pode emitir o mesma instrução SQL usando a biblioteca de cliente do Spanner para Ruby.

Use o método Client#execute (em inglês) para executar a consulta SQL. Use um símbolo :ColumnName do Ruby para acessar dados de uma coluna específica de uma linha.

Veja como emitir a consulta e acessar os dados:

# project_id  = "Your Google Cloud project ID"
# instance_id = "Your Spanner instance ID"
# database_id = "Your Spanner database ID"

require "google/cloud/spanner"

spanner = Google::Cloud::Spanner.new project: project_id
client  = spanner.client instance_id, database_id

client.execute("SELECT SingerId, AlbumId, AlbumTitle FROM Albums").rows.each do |row|
  puts "#{row[:SingerId]} #{row[:AlbumId]} #{row[:AlbumTitle]}"
end

Execute a amostra usando o argumento query_data.

bundle exec ruby spanner_samples.rb query_data test-instance example-db

Você verá o resultado a seguir:

1 1 Total Junk
1 2 Go, Go, Go
2 1 Green
2 2 Forever Hold Your Peace
2 3 Terrified

Consulta usando um parâmetro SQL

Se o aplicativo tiver uma consulta executada com frequência, é possível melhorar a performance fazendo a parametrização. A consulta paramétrica resultante pode ser armazenada em cache e reutilizada, o que reduz os custos de compilação. Para mais informações, consulte Use parâmetros de consulta para acelerar as consultas executadas com frequência.

Este é um exemplo de como usar um parâmetro na cláusula WHERE para registros de consulta que contêm um valor específico para LastName.

# project_id  = "Your Google Cloud project ID"
# instance_id = "Your Spanner instance ID"
# database_id = "Your Spanner database ID"

require "google/cloud/spanner"

spanner = Google::Cloud::Spanner.new project: project_id
client  = spanner.client instance_id, database_id

sql_query = "SELECT SingerId, FirstName, LastName
             FROM Singers
             WHERE LastName = @lastName"

params      = { lastName: "Garcia" }
param_types = { lastName: :STRING }

client.execute(sql_query, params: params, types: param_types).rows.each do |row|
  puts "#{row[:SingerId]} #{row[:FirstName]} #{row[:LastName]}"
end

Execute a amostra usando o argumento query_with_parameter.

bundle exec ruby spanner_samples.rb query_with_parameter test-instance example-db

Você verá o seguinte resultado:

12 Melissa Garcia

Ler dados usando a API de leitura

Além da interface SQL, o Spanner também dá suporte a uma interface de leitura automática.

Use o método Client#read da classe Client (links em inglês) para ler linhas do banco de dados.

Veja como ler os dados:

# project_id  = "Your Google Cloud project ID"
# instance_id = "Your Spanner instance ID"
# database_id = "Your Spanner database ID"

require "google/cloud/spanner"

spanner = Google::Cloud::Spanner.new project: project_id
client  = spanner.client instance_id, database_id

client.read("Albums", [:SingerId, :AlbumId, :AlbumTitle]).rows.each do |row|
  puts "#{row[:SingerId]} #{row[:AlbumId]} #{row[:AlbumTitle]}"
end

Execute a amostra usando o argumento read_data.

bundle exec ruby spanner_samples.rb read_data test-instance example-db

Você verá uma saída como:

1 1 Total Junk
1 2 Go, Go, Go
2 1 Green
2 2 Forever Hold Your Peace
2 3 Terrified

Atualizar o esquema do banco de dados

Suponha que você precise adicionar uma nova coluna denominada MarketingBudget à tabela Albums. Para isso, é necessário atualizar seu esquema de banco de dados. O Spanner oferece suporte a atualizações de esquema em um banco de dados enquanto esse banco continua a veicular o tráfego. Para fazer atualizações no esquema, não é necessário desconectar o banco de dados nem bloquear tabelas ou colunas inteiras. É possível continuar gravando dados no banco de dados durante a atualização do esquema. Leia mais sobre as atualizações de esquema compatíveis e o desempenho das alterações de esquema em Fazer atualizações de esquema.

Adicionar uma coluna

É possível adicionar uma coluna na linha de comando usando a Google Cloud CLI ou programaticamente usando a biblioteca de cliente do Spanner para Ruby.

Na linha de comando

Use o seguinte comando ALTER TABLE para adicionar a nova coluna à tabela:

GoogleSQL

gcloud spanner databases ddl update example-db --instance=test-instance \
    --ddl='ALTER TABLE Albums ADD COLUMN MarketingBudget INT64'

PostgreSQL

gcloud spanner databases ddl update example-db --instance=test-instance \
    --ddl='ALTER TABLE Albums ADD COLUMN MarketingBudget BIGINT'

Você verá:

Schema updating...done.

Usar a biblioteca de cliente do Spanner para Ruby

Use o Database#update da classe Database para modificar o esquema:

# project_id  = "Your Google Cloud project ID"
# instance_id = "Your Spanner instance ID"
# database_id = "Your Spanner database ID"

require "google/cloud/spanner"
require "google/cloud/spanner/admin/database"

database_admin_client = Google::Cloud::Spanner::Admin::Database.database_admin

db_path = database_admin_client.database_path project: project_id,
                                              instance: instance_id,
                                              database: database_id

job = database_admin_client.update_database_ddl database: db_path,
                                                statements: [
                                                  "ALTER TABLE Albums ADD COLUMN MarketingBudget INT64"
                                                ]

puts "Waiting for database update to complete"

job.wait_until_done!

puts "Added the MarketingBudget column"

Execute a amostra usando o argumento add_column.

bundle exec ruby spanner_samples.rb add_column test-instance example-db

Você verá:

Added the MarketingBudget column

Gravar dados na nova coluna

O código a seguir grava dados na coluna nova. Ele define MarketingBudget como 100000 para a linha indexada por Albums(1, 1) e como 500000 para a linha indexada por Albums(2, 2).

# project_id  = "Your Google Cloud project ID"
# instance_id = "Your Spanner instance ID"
# database_id = "Your Spanner database ID"

require "google/cloud/spanner"

spanner = Google::Cloud::Spanner.new project: project_id
client  = spanner.client instance_id, database_id

client.commit do |c|
  c.update "Albums", [
    { SingerId: 1, AlbumId: 1, MarketingBudget: 100_000 },
    { SingerId: 2, AlbumId: 2, MarketingBudget: 500_000 }
  ]
end

puts "Updated data"

Execute a amostra usando o argumento update_data.

bundle exec ruby spanner_samples.rb update_data test-instance example-db

Você verá:

Updated data

Também é possível executar uma consulta SQL ou uma chamada de leitura para coletar os valores que você acabou de gravar.

Veja a seguir o código para executar a consulta:

# project_id  = "Your Google Cloud project ID"
# instance_id = "Your Spanner instance ID"
# database_id = "Your Spanner database ID"

require "google/cloud/spanner"

spanner = Google::Cloud::Spanner.new project: project_id
client  = spanner.client instance_id, database_id

client.execute("SELECT SingerId, AlbumId, MarketingBudget FROM Albums").rows.each do |row|
  puts "#{row[:SingerId]} #{row[:AlbumId]} #{row[:MarketingBudget]}"
end

Para executar essa consulta, execute a amostra usando o argumento query_data_with_new_column.

bundle exec ruby spanner_samples.rb query_data_with_new_column test-instance example-db

Você verá:

1 1 100000
1 2
2 1
2 2 500000
2 3

Atualizar dados

É possível atualizar dados usando DML em uma transação de leitura/gravação.

Use o método execute_update() para executar uma instrução DML.

# project_id  = "Your Google Cloud project ID"
# instance_id = "Your Spanner instance ID"
# database_id = "Your Spanner database ID"

require "google/cloud/spanner"

spanner         = Google::Cloud::Spanner.new project: project_id
client          = spanner.client instance_id, database_id
transfer_amount = 200_000

client.transaction do |transaction|
  first_album = transaction.execute(
    "SELECT MarketingBudget from Albums
     WHERE SingerId = 1 and AlbumId = 1"
  ).rows.first
  second_album = transaction.execute(
    "SELECT MarketingBudget from Albums
    WHERE SingerId = 2 and AlbumId = 2"
  ).rows.first
  raise "The second album does not have enough funds to transfer" if second_album[:MarketingBudget] < transfer_amount

  new_first_album_budget  = first_album[:MarketingBudget] + transfer_amount
  new_second_album_budget = second_album[:MarketingBudget] - transfer_amount

  transaction.execute_update(
    "UPDATE Albums SET MarketingBudget = @albumBudget WHERE SingerId = 1 and AlbumId = 1",
    params: { albumBudget: new_first_album_budget }
  )
  transaction.execute_update(
    "UPDATE Albums SET MarketingBudget = @albumBudget WHERE SingerId = 2 and AlbumId = 2",
    params: { albumBudget: new_second_album_budget }
  )
end

puts "Transaction complete"

Execute a amostra usando o argumento write_with_transaction_using_dml.

bundle exec ruby spanner_samples.rb write_with_transaction_using_dml test-instance example-db

Você verá:

Transaction complete

Usar um índice secundário

Suponha que você queira buscar todas as linhas de Albums que tenham valores AlbumTitle em um determinado intervalo. É possível ler todos os valores da coluna AlbumTitle usando uma instrução SQL ou uma chamada de leitura e descartar as linhas que não satisfazem os critérios, mas fazer essa verificação na tabela inteira é caro, especialmente para tabelas com muitas linhas. Em vez disso, acelere a recuperação de linhas ao pesquisar por colunas de chaves não primárias por meio da criação de um índice secundário na tabela.

Adicionar um índice secundário a uma tabela requer uma atualização de esquema. Como outras atualizações de esquema, o Spanner é compatível com a adição de um índice enquanto o banco de dados continua a veicular o tráfego. O Spanner preenche automaticamente o com os dados atuais. Os preenchimentos podem levar alguns minutos para serem concluídos, mas você não precisa ficar off-line ou evitar gravar na tabela indexada durante esse processo. Para mais detalhes, consulte Adicione um índice secundário.

Depois que você adiciona um índice secundário, o Spanner o usa automaticamente para Consultas SQL que provavelmente serão executadas mais rapidamente com o índice. Se você usar a interface de leitura, deverá especificar o índice que quer usar.

Adicionar um índice secundário

É possível adicionar um índice na linha de comando usando a CLI gcloud ou programaticamente, usando a biblioteca de cliente do Spanner para Ruby.

Na linha de comando

Use o comando CREATE INDEX a seguir para adicionar um índice ao banco de dados:

gcloud spanner databases ddl update example-db --instance=test-instance \
    --ddl='CREATE INDEX AlbumsByAlbumTitle ON Albums(AlbumTitle)'

Você verá:

Schema updating...done.

Como usar a biblioteca de cliente do Spanner para Ruby

Use o método Database#update da classe Database (links em inglês) para adicionar um índice:

# project_id  = "Your Google Cloud project ID"
# instance_id = "Your Spanner instance ID"
# database_id = "Your Spanner database ID"

require "google/cloud/spanner"
require "google/cloud/spanner/admin/database"

database_admin_client = Google::Cloud::Spanner::Admin::Database.database_admin

db_path = database_admin_client.database_path project: project_id,
                                              instance: instance_id,
                                              database: database_id

job = database_admin_client.update_database_ddl database: db_path,
                                                statements: [
                                                  "CREATE INDEX AlbumsByAlbumTitle ON Albums(AlbumTitle)"
                                                ]

puts "Waiting for database update to complete"

job.wait_until_done!

puts "Added the AlbumsByAlbumTitle index"

Execute a amostra usando o argumento create_index.

bundle exec ruby spanner_samples.rb create_index test-instance example-db

A adição do índice pode levar alguns minutos. Depois da adição, você verá:

Added the AlbumsByAlbumTitle index

Ler usando o índice

Para consultas SQL, o Spanner usa automaticamente um índice adequado. Na interface de leitura, especifique o índice em sua solicitação.

Para usar o índice na interface de leitura, forneça um parâmetro index ao método read da classe Client (links em inglês).

# project_id  = "Your Google Cloud project ID"
# instance_id = "Your Spanner instance ID"
# database_id = "Your Spanner database ID"

require "google/cloud/spanner"

spanner = Google::Cloud::Spanner.new project: project_id
client  = spanner.client instance_id, database_id

result = client.read "Albums", [:AlbumId, :AlbumTitle],
                     index: "AlbumsByAlbumTitle"

result.rows.each do |row|
  puts "#{row[:AlbumId]} #{row[:AlbumTitle]}"
end

Execute a amostra usando o argumento read_data_with_index.

bundle exec ruby spanner_samples.rb read_data_with_index test-instance example-db

Você verá:

2 Forever Hold Your Peace
2 Go, Go, Go
1 Green
3 Terrified
1 Total Junk

Adicionar um índice para leituras somente de índice

Você deve ter notado que o exemplo de leitura anterior não inclui a leitura na coluna MarketingBudget. Isso ocorre porque a interface de leitura do Spanner não oferece suporte à capacidade de mesclar um índice com uma tabela de dados para procurar valores que não estão armazenados no índice.

Crie uma definição alternativa de AlbumsByAlbumTitle que armazene uma cópia de MarketingBudget no índice.

Na linha de comando

GoogleSQL

gcloud spanner databases ddl update example-db --instance=test-instance \
    --ddl='CREATE INDEX AlbumsByAlbumTitle2 ON Albums(AlbumTitle) STORING (MarketingBudget)

PostgreSQL

gcloud spanner databases ddl update example-db --instance=test-instance \
    --ddl='CREATE INDEX AlbumsByAlbumTitle2 ON Albums(AlbumTitle) INCLUDE (MarketingBudget)

A adição do índice pode levar alguns minutos. Depois da adição, você verá:

Schema updating...done.

Como usar a biblioteca de cliente do Spanner para Ruby

Use o Database#update da classe Database para adicionar um índice com uma cláusula STORING:

# project_id  = "Your Google Cloud project ID"
# instance_id = "Your Spanner instance ID"
# database_id = "Your Spanner database ID"

require "google/cloud/spanner"
require "google/cloud/spanner/admin/database"

database_admin_client = Google::Cloud::Spanner::Admin::Database.database_admin

db_path = database_admin_client.database_path project: project_id,
                                              instance: instance_id,
                                              database: database_id

job = database_admin_client.update_database_ddl database: db_path,
                                                statements: [
                                                  "CREATE INDEX AlbumsByAlbumTitle2 ON Albums(AlbumTitle)
   STORING (MarketingBudget)"
                                                ]

puts "Waiting for database update to complete"

job.wait_until_done!

puts "Added the AlbumsByAlbumTitle2 storing index"

Execute a amostra usando o argumento create_storing_index.

bundle exec ruby spanner_samples.rb create_storing_index test-instance example-db

Você verá:

Added the AlbumsByAlbumTitle2 index

Agora é possível executar uma leitura que busque todas as colunas AlbumId, AlbumTitle e MarketingBudget do índice AlbumsByAlbumTitle2:

# project_id  = "Your Google Cloud project ID"
# instance_id = "Your Spanner instance ID"
# database_id = "Your Spanner database ID"

require "google/cloud/spanner"

spanner = Google::Cloud::Spanner.new project: project_id
client  = spanner.client instance_id, database_id

result = client.read "Albums", [:AlbumId, :AlbumTitle, :MarketingBudget],
                     index: "AlbumsByAlbumTitle2"

result.rows.each do |row|
  puts "#{row[:AlbumId]} #{row[:AlbumTitle]} #{row[:MarketingBudget]}"
end

Execute a amostra usando o argumento read_data_with_storing_index.

bundle exec ruby spanner_samples.rb read_data_with_storing_index test-instance example-db

Você verá uma saída como:

2 Forever Hold Your Peace 300000
2 Go, Go, Go
1 Green
3 Terrified
1 Total Junk 300000

Recuperar dados usando transações somente leitura

Suponha que você queira executar mais de uma leitura no mesmo carimbo de data/hora. As transações somente leitura observam um prefixo consistente do histórico de confirmações da transação. Portanto, o aplicativo sempre recebe dados consistentes. Use um objeto Snapshot (em inglês) para executar transações somente leitura. Use o método snapshot da classe Client (links em inglês) para receber um objeto Snapshot.

Veja a seguir como executar uma consulta e fazer uma leitura na mesma transação somente leitura.

# project_id  = "Your Google Cloud project ID"
# instance_id = "Your Spanner instance ID"
# database_id = "Your Spanner database ID"

require "google/cloud/spanner"

spanner = Google::Cloud::Spanner.new project: project_id
client  = spanner.client instance_id, database_id

client.snapshot do |snapshot|
  snapshot.execute("SELECT SingerId, AlbumId, AlbumTitle FROM Albums").rows.each do |row|
    puts "#{row[:AlbumId]} #{row[:AlbumTitle]} #{row[:SingerId]}"
  end

  # Even if changes occur in-between the reads, the transaction ensures that
  # both return the same data.
  snapshot.read("Albums", [:AlbumId, :AlbumTitle, :SingerId]).rows.each do |row|
    puts "#{row[:AlbumId]} #{row[:AlbumTitle]} #{row[:SingerId]}"
  end
end

Execute a amostra usando o argumento read_only_transaction.

bundle exec ruby spanner_samples.rb read_only_transaction test-instance example-db

Você verá uma saída como:

2 Forever Hold Your Peace 2
2 Go, Go, Go 1
1 Green 2
3 Terrified 2
1 Total Junk 1
1 Total Junk 1
2 Go, Go, Go 1
1 Green 2
2 Forever Hold Your Peace 2
3 Terrified 2

Limpeza

Para não gerar cobranças extras na sua conta do Google Cloud pelos recursos usados neste tutorial, suspenda o banco de dados e exclua a instância que você criou.

Excluir o banco de dados

Se você excluir uma instância, todos os bancos de dados nela serão excluídos automaticamente. Nesta etapa, mostramos como excluir um banco de dados sem remover a instância. Ainda pode haver cobrança em relação à instância.

Na linha de comando

gcloud spanner databases delete example-db --instance=test-instance

Use o console do Google Cloud

  1. Acesse a página Instâncias do Spanner no console do Google Cloud.

    Acessar a página "Instâncias"

  2. Clique na instância.

  3. Clique no banco de dados que você quer excluir.

  4. Na página Detalhes do banco de dados, clique em Excluir.

  5. Confirme se quer excluir o banco de dados e clique em Excluir.

Excluir a instância

A exclusão de uma instância descarta automaticamente todos os bancos de dados criados nela.

Na linha de comando

gcloud spanner instances delete test-instance

Use o console do Google Cloud

  1. Acesse a página Instâncias do Spanner no console do Google Cloud.

    Acessar a página "Instâncias"

  2. Clique na sua instância.

  3. Clique em Excluir.

  4. Confirme se quer excluir a instância e clique em Excluir.

A seguir