Read-only Transactions via Snapshots

ASnapshot represents a read-onlytransaction: when multiple read operations are performed via a Snapshot,the results are consistent as of a particular point in time.

Beginning a Snapshot

To begin using a snapshot using the default “bound” (which is “strong”),meaning all reads are performed at a timestamp where all previously-committedtransactions are visible:

with database.snapshot() as snapshot:    ...

You can also specify a weaker bound, which can either be to perform allreads as of a given timestamp:

import datetimeTIMESTAMP = datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc)with database.snapshot(read_timestamp=TIMESTAMP) as snapshot:    ...

or as of a given duration in the past:

import datetimeDURATION = datetime.timedelta(seconds=5)with database.snapshot(exact_staleness=DURATION) as snapshot:    ...

Single Use and Multiple Use Snapshots

In the context of read only transactions,read andexecute_sqlmethods can be used multiple times if you specifymulti_use=Truein the constructor of the snapshot. However,multi_use=True isincompatible with eithermax_staleness and/ormin_read_timestamp.

Otherwisemulti_use defaults toFalse and the snapshot cannot bereused.

with database.snapshot(multi_use=True) as snapshot:    ...

begin() can only be used on asnapshot withmulti_use=True. In which case it is also necessaryto call if you need to have multiple pending operations.

Read Table Data

To read data for selected rows from a table in the database, callread() which will returnall rows specified inkeyset, or fail if the result set is too large,

with database.snapshot() as snapshot:    result = snapshot.read(        table='table-name', columns=['first_name', 'last_name', 'age'],        keyset=spanner.KeySet([['phred@example.com'], ['bharney@example.com']]))    for row in result:        print(row)

NOTE: Perform all iterations within the context of thewith database.snapshot()block.

Execute a SQL Select Statement

To read data from tables in the database using a query, callexecute_sql()which will return all rows matching the query, or fail if theresult set is too large,

with database.snapshot() as snapshot:    QUERY = (        'SELECT e.first_name, e.last_name, p.telephone '        'FROM employees as e, phones as p '        'WHERE p.employee_id == e.employee_id')    result = snapshot.execute_sql(QUERY)    for row in result:        print(row)

NOTE: Perform all iteration within the context of thewith database.snapshot()block.

Next Step

Next, learn aboutRead-write Transactions.

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-07-09 UTC.