This page describes how to insert, update, and delete data using mutations. A mutation represents a sequence of inserts, updates, and deletes that Spanner applies atomically to different rows and tables in a database. Mutations are designed for writing data. They can't read data from your tables. Many update operations must read existing data before performing modifications. For these use cases, you must use a read-write transaction, which lets Spanner read rows and then apply mutations within the same atomic operation.
Although you can commit mutations by using gRPC or REST, it is more common to access the APIs through the client libraries.
If you need to commit a large number of blind writes, but don't require an atomic transaction, you can bulk modify your Spanner tables using batch write. For more information, see Modify data using batch writes.
Insert new rows in a table
C++
You write data using the InsertMutationBuilder() function.
Client::Commit() adds new rows to a table. All inserts in
a single batch are applied atomically.
This code shows how to write the data:
C#
You can insert data using the
connection.CreateInsertCommand() method, which
creates a new SpannerCommand to insert rows into a table. The
SpannerCommand.ExecuteNonQueryAsync() method adds new
rows to the table.
This code shows how to insert data:
Go
You write data using a
Mutation. A Mutation is
a container for mutation operations. A Mutation represents a sequence of
inserts, updates, or deletes that can be applied atomically to
different rows and tables in a Spanner database.
Use Mutation.InsertOrUpdate()
to construct an INSERT_OR_UPDATE mutation, which adds a new row or updates
column values if the row already exists. Alternatively, use
Mutation.Insert()
method to construct an INSERT mutation, which adds a new row.
Client.Apply() applies
mutations atomically to a database.
This code shows how to write the data:
Java
You write data using a Mutation object. A Mutation
object is a container for mutation operations. A Mutation represents a
sequence of inserts, updates, and deletes that Spanner applies
atomically to different rows and tables in a Spanner database.
The newInsertBuilder() method in the Mutation
class constructs an INSERT mutation, which inserts a new
row in a table. If the row already exists, the write fails. Alternatively,
you can use the newInsertOrUpdateBuilder method
to construct an INSERT_OR_UPDATE mutation, which
updates column values if the row already exists.
The write() method in the DatabaseClient class writes
the mutations. All mutations in a single batch are applied atomically.
This code shows how to write the data:
Node.js
You write data using a
Table object. The
Table.insert()
method adds new rows to the table. All inserts in a single batch are applied
atomically.
This code shows how to write the data:
PHP
You write data using the
Database::insertBatch
method. insertBatch adds new rows to a table. All inserts in a single
batch are applied atomically.
This code shows how to write the data:
Python
You write data using a Batch object. A Batch object is
a container for mutation operations. A mutation represents a sequence of
inserts, updates, or deletes that can be applied atomically to
different rows and tables in a Spanner database.
The insert() method in the Batch class is used to
add one or more insert mutations to the batch. All mutations in a single
batch are applied atomically.
This code shows how to write the data:
Ruby
You write data using a
Client
object. The
Client#commit
method creates and commits a transaction for writes that execute atomically
at a single logical point in time across columns, rows, and tables in a
database.
This code shows how to write the data:
Update rows in a table
Suppose that sales of Albums(1, 1) are lower than expected. As a result, you
want to move $200,000 from the marketing budget of Albums(2, 2) to
Albums(1, 1), but only if the money is available in the budget of
Albums(2, 2).
C++
Use the Transaction() function to run a transaction for a client.
Here's the code to run the transaction:
C#
For .NET Standard 2.0 (or .NET 4.5) and newer, you can use the .NET framework's
TransactionScope() to run a transaction. For all supported
versions of .NET, you can create a transaction by setting the result of
SpannerConnection.BeginTransactionAsync as the Transaction property of
SpannerCommand.
Here are the two ways to run the transaction:
.NET Standard 2.0
.NET Standard 1.5
Go
Use the ReadWriteTransaction
type for executing a body of work in the context of a read-write transaction.
Client.ReadWriteTransaction()
returns a ReadWriteTransaction object.
The sample uses ReadWriteTransaction.ReadRow()
to retrieve a row of data.
The sample also uses ReadWriteTransaction.BufferWrite(),
which adds a list of mutations to the set of updates that will be applied
when the transaction is committed.
The sample also uses the Key
type, which represents a row key in a Spanner table or index.
Java
Use the TransactionRunnerinterface for executing
a body of work in the context of a read-write transaction. This interface
contains the method run(), which is used to execute a read-
write transaction, with retries as necessary. The
readWriteTransaction method of the DatabaseClient
class returns a TransactionRunner object for executing a single logical
transaction.
The TransactionRunner.TransactionCallable
class contains a run() method for performing a single attempt of a
transaction. run() takes a
TransactionContext object, which is a context
for a transaction.
The sample uses the Struct class, which is handy for
storing the results of the readRow() calls. The sample also uses the
Key class, which represents a row key in a Spanner
table or index.
Here's the code to run the transaction:
Node.js
Use Database.runTransaction()
to run a transaction.
Here's the code to run the transaction:
PHP
Use Database::runTransaction
to run a transaction.
Here's the code to run the transaction:
Python
Use the run_in_transaction()
method of the Database
class to run a transaction.
Here's the code to run the transaction:
Ruby
Use the transaction
method of the Client
class to run a transaction.
Here's the code to run the transaction:
Delete rows in a table
Each client library provides multiple ways to delete rows:
- Delete all the rows in a table.
- Delete a single row by specifying the key column values for the row.
- Delete a group of rows by creating a key range.
- Delete rows in an interleaved table by deleting the parent rows, if the
interleaved table includes
ON DELETE CASCADEin its schema definition.
C++
Delete rows using the DeleteMutationBuilder() function for a client.
This code shows how to delete the data:
C#
Delete rows using the
connection.CreateDeleteCommand() method, which
creates a new SpannerCommand to delete rows. The
SpannerCommand.ExecuteNonQueryAsync() method deletes the
rows from the table.
This example deletes the rows in the Singers table individually. The rows
in the Albums table are deleted because the Albums table is interleaved
in the Singers table and is defined with ON DELETE CASCADE.
Go
Delete rows using a Mutation. Use the
Mutation.Delete() method to construct a DELETE mutation,
which deletes a row. The Client.Apply() method applies
mutations atomically to the database.
This example deletes the rows in the Albums table individually, and then
deletes all the rows in the Singers table using a KeyRange.
Java
Delete rows using the Mutation.delete() method.
This examples uses the KeySet.all() method to delete all
the rows in the Albums table. After deleting the rows in the Albums
table, the example deletes the rows in the Singers table individually
using keys created with the KeySet.singleKey() method.
Node.js
Delete rows using the table.deleteRows() method.
This example uses the table.deleteRows() method to delete all the rows
from the Singers table. The rows in the Albums table are deleted because
the Albums table is interleaved in Singers table and is defined with ON
DELETE CASCADE.
PHP
Delete rows using the Database::delete() method. The
Database::delete() method page includes an example.
Python
Delete rows using the Batch.delete() method.
This example deletes all the rows in the Albums and Singers tables
individually using a KeySet object.
Ruby
Delete rows using the Client#delete method. The
Client#delete page includes an example.