Python Client for Cloud Spanner¶
Cloud Spanner is the world’s first fully managed relational database service to offer both strong consistency and horizontal scalability for mission-critical online transaction processing (OLTP) applications. With Cloud Spanner you enjoy all the traditional benefits of a relational database; but unlike any other relational database service, Cloud Spanner scales horizontally to hundreds or thousands of servers to handle the biggest transactional workloads.
Quick Start¶
In order to use this library, you first need to go through the following steps:
Installation¶
Install this library in a virtualenv using pip. virtualenv is a tool to create isolated Python environments. The basic problem it addresses is one of dependencies and versions, and indirectly permissions.
With virtualenv, it’s possible to install this library without needing system install permissions, and without clashing with the installed system dependencies.
Supported Python Versions¶
Python >= 3.7
Deprecated Python Versions¶
Python == 2.7. Python == 3.5. Python == 3.6.
Mac/Linux¶
pip install virtualenv
virtualenv <your-env>
source <your-env>/bin/activate
<your-env>/bin/pip install google-cloud-spanner
Windows¶
pip install virtualenv
virtualenv <your-env>
<your-env>\Scripts\activate
<your-env>\Scripts\pip.exe install google-cloud-spanner
Example Usage¶
Executing Arbitrary SQL in a Transaction¶
Generally, to work with Cloud Spanner, you will want a transaction. The
preferred mechanism for this is to create a single function, which executes
as a callback to database.run_in_transaction
:
# First, define the function that represents a single "unit of work"
# that should be run within the transaction.
def update_anniversary(transaction, person_id, unix_timestamp):
# The query itself is just a string.
#
# The use of @parameters is recommended rather than doing your
# own string interpolation; this provides protections against
# SQL injection attacks.
query = """SELECT anniversary FROM people
WHERE id = @person_id"""
# When executing the SQL statement, the query and parameters are sent
# as separate arguments. When using parameters, you must specify
# both the parameters themselves and their types.
row = transaction.execute_sql(
query=query,
params={'person_id': person_id},
param_types={
'person_id': types.INT64_PARAM_TYPE,
},
).one()
# Now perform an update on the data.
old_anniversary = row[0]
new_anniversary = _compute_anniversary(old_anniversary, years)
transaction.update(
'people',
['person_id', 'anniversary'],
[person_id, new_anniversary],
)
# Actually run the `update_anniversary` function in a transaction.
database.run_in_transaction(update_anniversary,
person_id=42,
unix_timestamp=1335020400,
)
Select records using a Transaction¶
Once you have a transaction object (such as the first argument sent to
run_in_transaction
), reading data is easy:
# Define a SELECT query.
query = """SELECT e.first_name, e.last_name, p.telephone
FROM employees as e, phones as p
WHERE p.employee_id == e.employee_id"""
# Execute the query and return results.
result = transaction.execute_sql(query)
for row in result.rows:
print(row)
Insert records using Data Manipulation Language (DML) with a Transaction¶
Use the execute_update()
method to execute a DML statement:
spanner_client = spanner.Client()
instance = spanner_client.instance(instance_id)
database = instance.database(database_id)
def insert_singers(transaction):
row_ct = transaction.execute_update(
"INSERT Singers (SingerId, FirstName, LastName) "
" VALUES (10, 'Virginia', 'Watson')"
)
print("{} record(s) inserted.".format(row_ct))
database.run_in_transaction(insert_singers)
Insert records using Mutations with a Transaction¶
To add one or more records to a table, use insert
:
transaction.insert(
'citizens',
columns=['email', 'first_name', 'last_name', 'age'],
values=[
['phred@exammple.com', 'Phred', 'Phlyntstone', 32],
['bharney@example.com', 'Bharney', 'Rhubble', 31],
],
)
Update records using Data Manipulation Language (DML) with a Transaction¶
spanner_client = spanner.Client()
instance = spanner_client.instance(instance_id)
database = instance.database(database_id)
def update_albums(transaction):
row_ct = transaction.execute_update(
"UPDATE Albums "
"SET MarketingBudget = MarketingBudget * 2 "
"WHERE SingerId = 1 and AlbumId = 1"
)
print("{} record(s) updated.".format(row_ct))
database.run_in_transaction(update_albums)
Update records using Mutations with a Transaction¶
Transaction.update
updates one or more existing records in a table. Fails
if any of the records does not already exist.
transaction.update(
'citizens',
columns=['email', 'age'],
values=[
['phred@exammple.com', 33],
['bharney@example.com', 32],
],
)
Connection API¶
Connection API represents a wrap-around for Python Spanner API, written in accordance with PEP-249, and provides a simple way of communication with a Spanner database through connection objects:
from google.cloud.spanner_dbapi.connection import connect
connection = connect("instance-id", "database-id")
connection.autocommit = True
cursor = connection.cursor()
cursor.execute("SELECT * FROM table_name")
result = cursor.fetchall()
Aborted Transactions Retry Mechanism¶
In !autocommit
mode, transactions can be aborted due to transient errors. In most cases retry of an aborted transaction solves the problem. To simplify it, connection tracks SQL statements, executed in the current transaction. In case the transaction aborted, the connection initiates a new one and re-executes all the statements. In the process, the connection checks that retried statements are returning the same results that the original statements did. If results are different, the transaction is dropped, as the underlying data changed, and auto retry is impossible.
Auto-retry of aborted transactions is enabled only for !autocommit
mode, as in autocommit
mode transactions are never aborted.
Next Steps¶
See the Client Library Documentation to learn how to connect to Cloud Spanner using this Client Library.
Read the Product documentation to learn more about the product and see How-to Guides.
Note
Because this client uses grpc
library, it is safe to
share instances across threads. In multiprocessing scenarios, the best
practice is to create client instances after the invocation of
os.fork()
by multiprocessing.pool.Pool
or
multiprocessing.Process
.
Usage Documentation¶
- Spanner Client Usage
- Table Admin Usage
- Batching Modifications
- Read-only Transactions via Snapshots
- Read-write Transactions
- Read Table Data
- Execute a SQL Select Statement
- Execute a SQL DML Statement
- Insert records using a Transaction
- Update records using a Transaction
- Insert or update records using a Transaction
- Replace records using a Transaction
- Delete records using a Transaction
- Using
run_in_transaction()
- Use a Transaction as a Context Manager
- Begin a Transaction
- Commit changes for a Transaction
- Roll back changes for a Transaction
- Database Admin Usage
- Non-Admin Database Usage
- Instance Admin Usage
API Documentation¶
- Advanced Session Pool Topics
- Tracing with OpenTelemetry
- Spanner Client
- Instance API
- Database API
- Table API
- Session API
- Session Pools API
- Keyset API
- Snapshot API
- Batch API
- Transaction API
- StreamedResultSet API
- Services for Google Cloud Spanner v1 API
- Types for Google Cloud Spanner v1 API
- Services for Google Cloud Spanner Admin Database v1 API
- Types for Google Cloud Spanner Admin Database v1 API
- DatabaseAdmin
- Services for Google Cloud Spanner Admin Instance v1 API
- Types for Google Cloud Spanner Admin Instance v1 API
- InstanceAdmin
Changelog¶
For a list of all google-cloud-spanner
releases:
- Changelog
- 3.50.1 (2024-11-14)
- 3.50.0 (2024-11-11)
- 3.49.1 (2024-09-06)
- 3.49.0 (2024-08-27)
- 3.48.0 (2024-07-30)
- 3.47.0 (2024-05-22)
- 3.46.0 (2024-05-02)
- 3.45.0 (2024-04-17)
- 3.44.0 (2024-03-13)
- 3.43.0 (2024-03-06)
- 3.42.0 (2024-01-30)
- 3.41.0 (2024-01-10)
- 3.40.1 (2023-08-17)
- 3.40.0 (2023-08-04)
- 3.39.0 (2023-08-02)
- 3.38.0 (2023-07-21)
- 3.37.0 (2023-07-21)
- 3.36.0 (2023-06-06)
- 3.35.1 (2023-05-25)
- 3.35.0 (2023-05-16)
- 3.34.0 (2023-05-16)
- 3.33.0 (2023-04-27)
- 3.32.0 (2023-04-25)
- 3.31.0 (2023-04-12)
- 3.30.0 (2023-03-28)
- 3.29.0 (2023-03-23)
- 3.28.0 (2023-02-28)
- 3.27.1 (2023-01-30)
- 3.27.0 (2023-01-10)
- 3.26.0 (2022-12-15)
- 3.25.0 (2022-12-13)
- 3.24.0 (2022-11-30)
- 3.23.0 (2022-11-07)
- 3.22.1 (2022-10-04)
- 3.22.0 (2022-09-26)
- 3.21.0 (2022-09-16)
- 3.20.0 (2022-08-30)
- 3.19.0 (2022-08-17)
- 3.18.0 (2022-08-12)
- 3.17.0 (2022-07-19)
- 3.16.0 (2022-07-11)
- 3.15.1 (2022-06-17)
- 3.15.0 (2022-06-17)
- 3.14.1 (2022-06-08)
- 3.14.0 (2022-04-20)
- 3.13.0 (2022-02-04)
- 3.12.1 (2022-01-06)
- 3.12.0 (2021-11-25)
- 3.11.1 (2021-10-04)
- 3.11.0 (2021-09-29)
- 3.10.0 (2021-09-17)
- 3.9.0 (2021-08-26)
- 3.8.0 (2021-08-15)
- 3.7.0 (2021-07-29)
- 3.6.0 (2021-06-23)
- 3.5.0 (2021-06-11)
- 3.4.0 (2021-04-29)
- 3.3.0 (2021-03-25)
- 3.2.0 (2021-03-02)
- 3.1.0 (2021-02-23)
- 3.0.0 (2021-01-15)
- 2.1.0 (2020-11-24)
- 2.0.0 (2020-11-11)
- 1.19.1 (2020-10-13)
- 1.19.0 (2020-09-08)
- 1.18.0 (2020-08-25)
- 1.17.1 (2020-06-24)
- 1.17.0 (2020-05-26)
- 1.16.0 (2020-05-05)
- 1.15.1 (2020-04-08)
- 1.15.0 (2020-03-17)
- 1.14.0 (2020-01-31)
- 1.13.0
- 1.12.0
- 1.11.0
- 1.10.0
- 1.9.0
- 1.8.0
- 1.7.1
- 1.7.0
- 1.6.1
- 1.6.0
- 1.5.0
- 1.4.0
- 1.3.0
- 1.2.0
- 1.1.0
- 1.0.0
- 0.30.0
- 0.29.0