All Products
Search
Document Center

Tablestore:Write data

Last Updated:Apr 10, 2026

Write method

Tablestore provides the PutRow, UpdateRow, and BatchWriteRow operations for writing data. Select the write method that best suits your scenario.

Write method

Description

Scenarios

Insert a single row of data

Call the PutRow operation to insert a new row. If the row already exists, Tablestore deletes the original row with all its columns and versions, and then inserts the new row.

Suitable for writing a small amount of data.

Update a single row of data

Call the UpdateRow operation to update a row. You can add or delete attribute columns, delete specific versions of an attribute column, or update the values of existing attribute columns. If the specified row does not exist, a new row is inserted.

Suitable for updating existing data, such as deleting attribute columns, deleting a specific version of a column, or modifying attribute column values.

Batch write data

Call the BatchWriteRow operation to perform multiple write operations in a single request or write data to multiple tables at once.

A BatchWriteRow operation consists of multiple PutRow, UpdateRow, and DeleteRow sub-operations. The process for constructing these sub-operations is the same as calling the PutRow, UpdateRow, and DeleteRow operations individually.

Suitable for scenarios where you need to write, delete, or update large amounts of data, or perform a mix of these operations.

Prerequisites

Insert a single row of data

Interface

/// <summary>
/// Writes a row of data based on the specified table name, primary key, and properties. Returns the capacity unit consumed by this operation.
/// </summary>
/// <param name="request">The request to insert data.</param>
/// <returns>The capacity unit consumed by this operation.</returns>
public PutRowResponse PutRow(PutRowRequest request);

/// <summary>
/// The asynchronous version of PutRow.
/// </summary>
public Task<PutRowResponse> PutRowAsync(PutRowRequest request);                    

Parameters

Parameter

Description

tableName

The name of the data table.

primaryKey

The primary key of the row. The primary key includes the name, type, and value of each primary key column.

Important
  • The number and types of the primary key columns must match those defined for the data table.

  • If a primary key column is an auto-increment column, set its value to a placeholder. For more information, see Auto-increment primary key column.

attribute

The attribute columns of the row. Each item includes the attribute name, attribute type (optional), attribute value, and timestamp (optional).

  • The attribute name is the name of the attribute column, and the attribute type is the data type of the attribute column. For more information, see Naming conventions and data types.

    The attribute type can be INTEGER, STRING (UTF-8 encoded), BINARY, BOOLEAN, or DOUBLE.

  • The timestamp is the version number of the data. It can be automatically generated by the system or customized. If you do not set this parameter, the system automatically generates a timestamp. For more information, see Data versions and lifecycle.

    • When the system automatically generates a version number, it uses the current UNIX timestamp in milliseconds (the number of milliseconds that have elapsed since 00:00:00 UTC on January 1, 1970) as the version number.

    • When you customize the version number, it must be a 64-bit UNIX timestamp in milliseconds and within the valid version range.

condition

Use a conditional update to set an existence condition for the original row or a value condition for a column in the original row. For more information, see Conditional update.

Note
  • Starting from .NET SDK 2.2.0, Condition supports both row conditions and column conditions.

  • Condition.IGNORE, Condition.EXPECT_EXIST, and Condition.EXPECT_NOT_EXIST are deprecated starting from .NET SDK 3.0.0. Replace them with new Condition (RowExistenceExpectation.IGNORE), new Condition (RowExistenceExpectation.EXPECT_EXIST), and new Condition (RowExistenceExpectation.EXPECT_NOT_EXIST).

  • RowExistenceExpectation.IGNORE indicates that new data is inserted regardless of whether the row exists. If the row already exists, the original data is overwritten.

  • RowExistenceExpectation.EXPECT_EXIST indicates that new data is inserted only if the row exists. The original data is overwritten.

  • RowExistenceExpectation.EXPECT_NOT_EXIST indicates that data is inserted only if the row does not exist.

Examples

Insert a row of data

The following example shows how to insert a row of data.

// Define the primary key of the row. It must be consistent with the definition in the TableMeta of the table.
var primaryKey = new PrimaryKey();
primaryKey.Add("pk0", new ColumnValue(0));
primaryKey.Add("pk1", new ColumnValue("abc"));

// Define the attribute columns to be written to the row.
var attribute = new AttributeColumns();
attribute.Add("col0", new ColumnValue(0));
attribute.Add("col1", new ColumnValue("a"));
attribute.Add("col2", new ColumnValue(true));

try
{
    // Construct a request object to insert data. RowExistenceExpectation.IGNORE indicates that new data is inserted regardless of whether the row exists.
    var request = new PutRowRequest("SampleTable", new Condition(RowExistenceExpectation.IGNORE),
                            primaryKey, attribute);

    // Call the PutRow operation to insert the data.
    otsClient.PutRow(request);

    // If no exception is thrown, the operation is successful.
    Console.WriteLine("Put row succeeded.");
}
catch (Exception ex)
{
    // If an exception is thrown, the operation failed. Handle the exception.
    Console.WriteLine("Put row failed, exception:{0}", ex.Message);
}                    

For the complete sample code, see PutRow@GitHub.

Use column and row conditions when inserting data

The following example executes an insert operation only if a row exists and `col0` is greater than 24.

// Define the primary key of the row. It must be consistent with the definition in the TableMeta of the table.
var primaryKey = new PrimaryKey();
primaryKey.Add("pk0", new ColumnValue(0));
primaryKey.Add("pk1", new ColumnValue("abc"));

// Define the attribute columns to be written to the row.
AttributeColumns attribute = new AttributeColumns();
attribute.Add("col0", new ColumnValue(0));
attribute.Add("col1", new ColumnValue("a"));
attribute.Add("col2", new ColumnValue(true));

// Allow inserting the row again and overwriting the original value if the value of the col0 column is greater than 24.
try
{
    var request = new PutRowRequest("SampleTable", new Condition(RowExistenceExpectation.EXPECT_EXIST),
                            primaryKey, attribute);
    request.Condition.ColumnCondition = new RelationalCondition("col0",
                                        CompareOperator.GREATER_THAN,
                                        new ColumnValue(24));
    otsClient.PutRow(request);

    Console.WriteLine("Put row succeeded.");
}
catch (Exception ex)
{
    Console.WriteLine("Put row failed. error:{0}", ex.Message);
}                   

For the complete sample code, see ConditionPutRow@GitHub.

Asynchronously insert data

The following example shows how to asynchronously insert multiple rows of data.

Important

Each asynchronous invocation starts a thread. If you start many time-consuming asynchronous invocations consecutively, a timeout may occur.

try
{
    var putRowTaskList = new List<Task<PutRowResponse>>();
    for (int i = 0; i < 100; i++)
    {
        // Define the primary key of the row. It must be consistent with the definition in the TableMeta of the table.
        var primaryKey = new PrimaryKey();
        primaryKey.Add("pk0", new ColumnValue(i));
        primaryKey.Add("pk1", new ColumnValue("abc"));

        // Define the attribute columns to be written to the row.
        var attribute = new AttributeColumns();
        attribute.Add("col0", new ColumnValue(i));
        attribute.Add("col1", new ColumnValue("a"));
        attribute.Add("col2", new ColumnValue(true));

        var request = new PutRowRequest("SampleTable", new Condition(RowExistenceExpectation.IGNORE),
                                        primaryKey, attribute);

        putRowTaskList.Add(otsClient.PutRowAsync(request));
    }

    // Wait for each asynchronous call to return and print the consumed CU value.
    foreach (var task in putRowTaskList)
    {
        task.Wait();
        Console.WriteLine("consumed read:{0}, write:{1}", task.Result.ConsumedCapacityUnit.Read,
                            task.Result.ConsumedCapacityUnit.Write);
    }

    // If no exception is thrown, the operation is successful.
    Console.WriteLine("Put row async succeeded.");
}
catch (Exception ex)
{
    // If an exception is thrown, the operation failed. Handle the exception.
    Console.WriteLine("Put row async failed. exception:{0}", ex.Message);
}                   

For the complete sample code, see PutRowAsync@GitHub.

Update a single row of data

Interface

/// <summary>
/// Updates the data of a specified row. If the row does not exist, a new row is created. If the row exists, the values of specified columns are added, modified, or deleted based on the request.
/// </summary>
/// <param name="request">The request object.</param>
public UpdateRowResponse UpdateRow(UpdateRowRequest request);

/// <summary>
/// The asynchronous version of UpdateRow.
/// </summary>
/// <param name="request">The request object.</param>
/// <returns></returns>
public Task<UpdateRowResponse> UpdateRowAsync(UpdateRowRequest request);            

Parameters

Parameter

Description

tableName

The name of the data table.

primaryKey

The primary key of the row. The primary key includes the primary key column name, type, and value.

Important

The number and types of the primary key columns that you set must be the same as those defined for the data table.

condition

For a conditional update, you can set conditions on the existence of the original row or on the column values of the original row. For more information, see Conditional updates.

attribute

The attribute columns to update.

Example

The following example shows how to update a row of data.

// Define the primary key of the row. The primary key must be the same as the one defined in TableMeta when the table was created.
PrimaryKey primaryKey = new PrimaryKey();
primaryKey.Add("pk0", new ColumnValue(0));
primaryKey.Add("pk1", new ColumnValue("abc"));

// Define the attribute columns to write to the row.
UpdateOfAttribute attribute = new UpdateOfAttribute();
attribute.AddAttributeColumnToPut("col0", new ColumnValue(0));
attribute.AddAttributeColumnToPut("col1", new ColumnValue("b")); // Change the original value 'a' to 'b'.
attribute.AddAttributeColumnToPut("col2", new ColumnValue(true));

try
{
    // Construct a request object to update the row. RowExistenceExpectation.IGNORE indicates that the row is updated whether it exists or not.
    var request = new UpdateRowRequest("SampleTable", new Condition(RowExistenceExpectation.IGNORE),
                                primaryKey, attribute);
    // Call the UpdateRow operation to update the data.
    otsClient.UpdateRow(request);

    // If no exception is thrown, the operation is successful.
    Console.WriteLine("Update row succeeded.");
}
catch (Exception ex)
{
    // If an exception is thrown, the operation failed. Handle the exception.
    Console.WriteLine("Update row failed, exception:{0}", ex.Message);
}           

For the complete sample code, see UpdateRow@GitHub.

Batch write data

Notes

API

/// <summary>
/// <para>Bulk inserts, updates, or deletes multiple rows of data in one or more tables.</para>
/// <para>The BatchWriteRow operation is a collection of multiple PutRow, UpdateRow, and DeleteRow operations. Each operation is executed independently, returns its own result, and consumes capacity units separately.</para>
/// <para>Compared to many single-row write operations, the BatchWriteRow operation reduces request response times and improves the data write speed.</para>
/// </summary>
/// <param name="request">The request instance.</param>
/// <returns>The response instance.</returns>
public BatchWriteRowResponse BatchWriteRow(BatchWriteRowRequest request);

/// <summary>
/// The asynchronous version of BatchWriteRow.
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public Task<BatchWriteRowResponse> BatchWriteRowAsync(BatchWriteRowRequest request);            

Example

The following example shows how to batch write 100 rows of data.

var TableName = "SampleTable";
// Construct a batch write request object and set the primary keys for 100 rows of data.
var request = new BatchWriteRowRequest();
var rowChanges = new RowChanges(TableName);
for (int i = 0; i < 100; i++)
{
    PrimaryKey primaryKey = new PrimaryKey();
    primaryKey.Add("pk0", new ColumnValue(i));
    primaryKey.Add("pk1", new ColumnValue("abc"));

    // Define the attribute columns to write to the row.
    UpdateOfAttribute attribute = new UpdateOfAttribute();
    attribute.AddAttributeColumnToPut("col0", new ColumnValue(0));
    attribute.AddAttributeColumnToPut("col1", new ColumnValue("a"));
    attribute.AddAttributeColumnToPut("col2", new ColumnValue(true));

    rowChanges.AddUpdate(new Condition(RowExistenceExpectation.IGNORE), primaryKey, attribute);
}

request.Add(TableName, rowChanges);

try
{
    // Call the BatchWriteRow API to write data.
    var response = otsClient.BatchWriteRow(request);
    var tableRows = response.TableRespones;
    var rows = tableRows[TableName];

    // A batch operation may partially succeed. Check the status of each row for success. For more information, see the GitHub link in the sample code.
}
catch (Exception ex)
{
    // If an exception is thrown, the execution failed. Handle the exception.
    Console.WriteLine("Batch put row failed, exception:{0}", ex.Message);
}           

For the complete sample code, see BatchWriteRow@GitHub.

FAQ

References

  • You can use conditional updates to update data based on specific conditions in high-concurrency applications. For more information, see Conditional update.

  • To provide real-time statistics for online applications, such as counting real-time page views (PVs) for posts, you can use atomic counters. For more information, see Atomic counter.

  • After you write data, you can read or delete data from the table as needed. For more information, see Read data or Delete data.