Database Admin Usage

After creating anInstance, you caninteract with individual databases for that instance.

List Databases

To iterate over all existing databases for an instance, use itslist_databases() method:

for database in instance.list_databases():    # `database` is a `Database` object.

This method yieldsDatabaseobjects.

Database Factory

To create aDatabase object:

database = instance.database(database_id, ddl_statements)
  • ddl_statements is a list of strings containing DDL statements for the new database.

You can also use thedatabase() methodon anInstance object to create a local wrapperfor a database that has already been created:

database = instance.database(existing_database_id)

Create a new Database

After creating the database object, use itscreate() method totrigger its creation on the server:

operation = database.create()

NOTE: Creating a database triggers a “long-running operation” andreturns aFuture-like object. Usetheresult() method to wait forand inspect the result.

Update an existing Database

After creating the database object, you can apply additional DDL statementsvia itsupdate_ddl() method:

operation = database.update_ddl(ddl_statements, operation_id)
  • ddl_statements is a list of strings containing DDL statements to beapplied to the database.

  • operation_id is a string ID for the long-running operation.

NOTE: Updating a database triggers a “long-running operation” andreturns anOperationobject. See Check on Current Database Operation for pollingto find out if the operation is completed.

Drop a Database

Drop a database using itsdrop() method:

database.drop()

Check on Current Database Operation

Thecreate() andupdate_ddl() methods of theDatabase object triggerlong-running operations on the server, and return operationsconforming to theFuture class.

>>> operation = database.create()>>> operation.result()

Non-Admin Database Usage

Use a Snapshot to Read / Query the Database

A snapshot represents a read-only point-in-time view of the database.

Callingsnapshot() withno arguments creates a snapshot with strong concurrency:

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

SeeSnapshot for the other optionswhich can be passed.

NOTE:snapshot() returns anobject intended to be used as a Python context manager (i.e., as thetarget of awith statement). Perform all iterations within thecontext of thewith database.snapshot() block.

SeeRead-only Transactions via Snapshots for more complete examples of snapshot usage.

Use a Batch to Modify Rows in the Database

A batch represents a bundled set of insert/upsert/update/delete operationson the rows of tables in the database.

with database.batch() as batch:     batch.insert_or_update(table, columns, rows)     batch.delete(table, keyset_to_delete)

NOTE:batch() returns anobject intended to be used as a Python context manager (i.e., as thetarget of awith statement). It applies any changes made insidethe block of itswith statement when exiting the block, unless anexception is raised within the block. Use the batch only insidethe block created by thewith statement.

SeeBatching Modifications for more complete examples of batch usage.

Use a Transaction to Query / Modify Rows in the Database

A transaction represents the union of a “strong” snapshot and a batch:it allowsread andexecute_sql operations, and accumulatesinsert/upsert/update/delete operations.

Because other applications may be performing concurrent updates whichwould invalidate the reads / queries, the work done by a transaction needsto be bundled as a retryable “unit of work” function, which takes thetransaction as a required argument:

def unit_of_work(transaction):    result = transaction.execute_sql(QUERY)    for emp_id, hours, pay in _compute_pay(result):        transaction.insert_or_update(            table='monthly_hours',            columns=['employee_id', 'month', 'hours', 'pay'],            values=[emp_id, month_start, hours, pay])database.run_in_transaction(unit_of_work)

NOTE:run_in_transaction()commits the transaction automatically if the “unit of work” functionreturns without raising an exception.

NOTE:run_in_transaction()retries the “unit of work” function if the read / query operationsor the commit are aborted due to concurrent updates.

SeeRead-write Transactions for more complete examples of transaction usage.

Configuring a session pool for a database

Under the covers, thesnapshot,batch, andrun_in_transactionmethods use a pool ofSession objectsto manage their communication with the back-end. You can configureone of the pools manually to control the number of sessions, timeouts, etc.,and then pass it to theDatabaseconstructor:

from google.cloud importspanner# Instantiate the Spanner client, and get the appropriate instance.client =spanner.Client()instance =client.instance(INSTANCE_NAME)# Create a database with a pool of a fixed size.pool =spanner.FixedSizePool(size=10, default_timeout=5)database = instance.database(DATABASE_NAME, pool=pool)

Note that creating a database with a pool will require the database toalready exist if the pool implementation needs to pre-create sessions(rather than creating them on demand, as the default implementation does).

You can supply your own pool implementation, which must satisfy thecontract laid out inAbstractSessionPool:

from google.cloud.spanner importAbstractSessionPoolclass MyCustomPool(AbstractSessionPool):     def __init__(self, database, custom_param):         super(MyCustomPool, self).__init__(database)         self.custom_param = custom_param     def get(self, read_only=False):         ...     def put(self, session, discard_if_full=True):         ...database = instance.database(DATABASE_NAME, pool=pool)pool = MyCustomPool(database, custom_param=42)

SeeAdvanced Session Pool Topics for more advanced coverage ofsession pools.

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-18 UTC.