Cloud Spanner
Cloud Spanner is a fully managed, mission-critical, relational database servicethat offers transactional consistency at global scale, schemas, SQL (ANSI 2011with extensions), and automatic, synchronous replication for high availability.
For more information about Cloud Spanner, read theCloud SpannerDocumentation.
The goal of google-cloud is to provide an API that is comfortable to Rubyists.Your authentication credentials are detected automatically in Google CloudPlatform (GCP), including Google Compute Engine (GCE), Google Kubernetes Engine(GKE), Google App Engine (GAE), Google Cloud Functions (GCF) and Cloud Run. Inother environments you can configure authentication easily, either directly inyour code or via environment variables. Read more about the options forconnecting in theAuthentication Guide.
Creating instances
When you first use Cloud Spanner, you must create an instance, which is anallocation of resources that are used by Cloud Spanner databases. When youcreate an instance, you choose where your data is stored and how many nodes areused for your data. (For more information, seeConfigurationGuide.
UseClient#create_instance to create an instance:
require"google/cloud/spanner"instance_admin_client=\Google::Cloud::Spanner::Admin::Instance.instance_adminproject_id:"my-project"project_path=\instance_admin_client.project_pathproject:"my-project"config_path=\instance_admin_client.instance_config_pathproject:"my-project",instance_config:"regional-us-central1"instance_path=\instance_admin_client.instance_pathproject:"my-project",instance:"my-instance"job=instance_admin_client.create_instanceparent:project_path,instance_id:"my-instance",instance:Google::Cloud::Spanner::Admin::Instance::V1::Instance.new({name:instance_pathdisplay_name:"My Instance",config:config_path,node_count:5,labels:{"production"::env}})job.wait_until_done!instance=job.results
Creating databases
Now that you have created an instance, you can create a database. CloudSpanner databases hold the tables and indexes that allow you to read andwrite data. You may create multiple databases in an instance.
UseClient#create_database to create a database:
require"google/cloud/spanner"db_admin_client=\Google::Cloud::Spanner::Admin::Database.database_adminproject_id:"my-project"instance_path=\db_admin_client.instance_pathproject:"my-project",instance:"my-instance"job=db_admin_client.create_databaseparent:instance_path,create_statement:"CREATE DATABASE my-database",job.wait_until_done!database=job.results
Updating database schemas
Cloud Spanner supports schema updates to a database while the databasecontinues to serve traffic. Schema updates do not require taking thedatabase offline and they do not lock entire tables or columns; you cancontinue writing data to the database during the schema update.
UseClient#update_database_ddl to execute one or more statements in Cloud Spanner'sData Definition Language (DDL):
require"google/cloud/spanner"db_admin_client=\Google::Cloud::Spanner::Admin::Database.database_adminproject_id:"my-project"db_path=db_admin_client.database_pathproject:"my-project",instance:"my-instance",database:"my-database"add_users_table_sql=%q( CREATE TABLE users ( id INT64 NOT NULL, username STRING(25) NOT NULL, name STRING(45) NOT NULL, email STRING(128), ) PRIMARY KEY(id))job=db_admin_client.update_database_ddldatabase:db_path,statements:[add_users_table_sql]job.wait_until_done!database=job.results
Creating clients
In order to read and/or write data, you must create a data client. You can thinkof a client as a database connection: All of your interactions with CloudSpanner data must go through a client. Typically you create a client when yourapplication starts up, then you re-use that client to read, write, and executetransactions.
UseProject#client to create a client:
require"google/cloud/spanner"spanner=Google::Cloud::Spanner.newdb=spanner.client"my-instance","my-database"results=db.execute"SELECT 1"results.rows.eachdo|row|putsrowend
Writing data
You write data using your client object. The client object supports variousmutation operations, as well as combinations of inserts, updates, deletes, etc.,that can be applied atomically to different rows and/or tables in a database.
UseClient#commit to execute variousmutations atomically at a single logical point in time. All changes areaccumulated in memory until the block completes. UnlikeClient#transaction, which can alsoperform reads, this operation accepts only mutations and makes a single APIrequest.
require"google/cloud/spanner"spanner=Google::Cloud::Spanner.newdb=spanner.client"my-instance","my-database"db.commitdo|c|c.update"users",[{id:1,username:"charlie94",name:"Charlie"}]c.insert"users",[{id:2,username:"harvey00",name:"Harvey"}]end
Querying data using SQL
Cloud Spanner supports a native SQL interface for reading data that is availablethroughClient#execute:
require"google/cloud/spanner"spanner=Google::Cloud::Spanner.newdb=spanner.client"my-instance","my-database"results=db.execute"SELECT * FROM users"results.rows.eachdo|row|puts"User#{row[:id]} is#{row[:name]}"end
Reading data using the read method
In addition to Cloud Spanner's SQL interface, Cloud Spanner also supports a readinterface. Use theClient#read method toread rows from the database, and use itskeys option to pass uniqueidentifiers as both lists and ranges:
require"google/cloud/spanner"spanner=Google::Cloud::Spanner.newdb=spanner.client"my-instance","my-database"results=db.read"users",[:id,:name],keys:1..5results.rows.eachdo|row|puts"User#{row[:id]} is#{row[:name]}"end
Using read-write transactions
When an operation might write data depending on values it reads, you should usea read-write transaction to perform the reads and writes atomically.
Suppose that sales ofAlbums(1, 1) are lower than expected and you want tomove $200,000 from the marketing budget ofAlbums(2, 2) to it, but only if thebudget ofAlbums(2, 2) is at least $300,000.
UseClient#transaction to executeboth reads and writes atomically at a single logical point in time. All changesare accumulated in memory until the block completes. Transactions will beautomatically retried when possible. This operation makes separate API requeststo begin and commit the transaction.
require"google/cloud/spanner"spanner=Google::Cloud::Spanner.newdb=spanner.client"my-instance","my-database"db.transactiondo|tx|# Read the second album budget.second_album_result=tx.read"Albums",["marketing_budget"],keys:[[2,2]],limit:1second_album_row=second_album_result.rows.firstsecond_album_budget=second_album_row.values.firsttransfer_amount=200000ifsecond_album_budget <300000=""#="" raising="" an="" exception="" will="" automatically="" roll="" back="" the="" transaction.="" raise="" "the="" second="" album="" doesn't="" have="" enough="" funds="" to="" transfer"="" end="" #="" read="" the="" first="" album's="" budget.="" first_album_result="tx.read" "albums",="" ["marketing_budget"],="" keys:="" [[1,="" 1]],="" limit:="" 1="" first_album_row="first_album_result.rows.first" first_album_budget="first_album_row.values.first" #="" update="" the="" budgets.="" second_album_budget="" -="transfer_amount" first_album_budget="" +="transfer_amount" puts="" "setting="" first="" album's="" budget="" to="" #{first_album_budget}="" and="" the="" "="" \="" "second="" album's="" budget="" to="" #{second_album_budget}."="" #="" update="" the="" rows.="" rows="[" {singer_id:="" 1,="" album_id:="" 1,="" marketing_budget:="" first_album_budget},="" {singer_id:="" 2,="" album_id:="" 2,="" marketing_budget:="" second_album_budget}="" ]="" tx.update="" "albums",="" rows="" end="">
Using read-only transactions
Suppose you want to execute more than one read at the same timestamp. Read-onlytransactions observe a consistent prefix of the transaction commit history, soyour application always gets consistent data. Because read-only transactions aremuch faster than locking read-write transactions, we strongly recommend that youdo all of your transaction reads in read-only transactions if possible.
Use aSnapshot object to execute statementsin a read-only transaction. The snapshot object is available via a blockprovided toClient#snapshot:
require"google/cloud/spanner"spanner=Google::Cloud::Spanner.newdb=spanner.client"my-instance","my-database"db.snapshotdo|snp|results_1=snp.execute"SELECT * FROM users"results_1.rows.eachdo|row|puts"User#{row[:id]} is#{row[:name]}"end# Perform another read using the `read` method. Even if the data# is updated in-between the reads, the snapshot ensures that both# return the same data.results_2=db.read"users",[:id,:name]results_2.rows.eachdo|row|puts"User#{row[:id]} is#{row[:name]}"endend
Deleting databases
UseClient#drop_database to delete a database:
require"google/cloud/spanner"db_admin_client=\Google::Cloud::Spanner::Admin::Database.database_adminproject_id:"my-project"db_path=db_admin_client.database_pathproject:"my-project",instance:"my-instance",database:"my-database"db_admin_client.drop_databasedatabase:db_path
Deleting instances
When you delete an instance, all databases within it are automatically deleted.(If you only delete databases and not your instance, you will still incurcharges for the instance.)
UseClient#delete_instance to delete an instance:
require"google/cloud/spanner"instance_admin_client=\Google::Cloud::Spanner::Admin::Instance.instance_adminproject_id:"my-project"instance_path=\instance_admin_client.instance_pathproject:"my-project",instance:"my-instance"instance_admin_client.delete_instancename:instance_path
Additional information
Cloud Spanner can be configured to use gRPC's logging. To learn more, see theLogging guide.
Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
Last updated 2025-11-17 UTC.