All Products
Search
Document Center

Tablestore:Write data

Last Updated:Feb 28, 2026

Tablestore provides three operations for writing data to tables: PutRow, UpdateRow, and BatchWriteRow.

Note

Rows are the basic units of tables. Each row consists of primary key columns and optional attribute columns. Primary key column names and types are the same across all rows in a table. Attribute columns can differ between rows. For more information, see Overview.

Operations

OperationScopeBehavior
PutRowSingle rowInserts a row. If a row with the same primary key exists, deletes all versions of data in all columns and writes the new data.
UpdateRowSingle rowAdds, updates, or removes attribute columns. Deletes a specific version of data from a column. If the row does not exist, inserts a new row (unless the request only removes columns).
BatchWriteRowMultiple rowsCombines multiple PutRow, UpdateRow, and DeleteRow sub-operations in a single request across one or more tables. Each sub-operation is performed and responded to independently.

Common settings

Before writing data, you can configure the following optional settings for any write operation:

  • Data version number: By default, Tablestore uses the current UNIX timestamp (milliseconds since January 1, 1970, 00:00:00 UTC) as the version number. Specify a custom version number if needed. For more information, see Data versions and TTL.

  • Conditional update: Set a row existence condition or a condition based on column values. For more information, see Conditional updates.

PutRow response

  • On success, Tablestore returns the number of capacity units (CUs) consumed.

  • On failure, Tablestore returns an error code (for example, parameter validation failure, excessive row data, or row existence check failure).

Note

For more information about error codes, see Error codes.

BatchWriteRow partial failure handling

When some rows fail in a BatchWriteRow request, Tablestore does not throw an exception. Instead, it returns a BatchWriteRowResponse that contains information about the failed rows. Always call the isAllSucceed method to check whether all rows were written successfully.

If the server detects invalid parameters in some operations, it may return an error before performing any operations in the request.

BatchWriteRow also supports per-operation conditions -- configure update conditions separately for each PutRow, UpdateRow, or DeleteRow sub-operation.

Use the Tablestore console

The Tablestore console supports inserting and updating a single row of data.

  1. Log on to the Tablestore console.

  2. On the Overview page, find the target instance and click Manage Instance in the Actions column.

  3. On the Tables tab of the Instance Details tab, click the name of the target table.

  4. On the Query Data tab of the Manage Table page, insert or update data.

Insert a single row

  1. Click Insert.

  2. In the Insert dialog box, enter values in the Primary Key Value column.

  3. Click the image icon and configure the Name, Type, Value, and Version parameters. To add multiple attribute columns, click the image icon each time to add a column and configure its parameters.

  4. Click OK.

Update a single row

  1. Select the row to update and click Update.

  2. In the Update dialog box, modify the attribute columns:

    • Add a column: Click the image icon and configure the parameters.

    • Remove a column: Select Delete All from the Actions drop-down list.

    • Delete a specific version: Select Delete from the Actions drop-down list and select the version number to delete.

    • Update a value: Select Update from the Actions drop-down list and modify the value.

  3. Click OK.

Use the Tablestore CLI

Insert a row

Run the put command. For more information, see Insert data.

The following example inserts a row where the first primary key column is 86 and the second primary key column is 6771. The row has two STRING attribute columns: name and country.

put --pk '["86", 6771]' --attr '[{"c":"name", "v":"redchen"}, {"c":"country", "v":"china"}]'

Update a row

Run the update command. For more information, see Update data.

The following example updates the row where the first primary key column is 86 and the second primary key column is 6771. The --condition ignore flag inserts data regardless of whether the row exists. If the row exists, the new data overwrites the existing data.

update --pk '["86", 6771]' --attr '[{"c":"name", "v":"redchen"}, {"c":"country", "v":"china"}]' --condition ignore

Use Tablestore SDKs

Write data using any of the following SDKs: Tablestore SDK for Java, Tablestore SDK for Go, Tablestore SDK for Python, Tablestore SDK for Node.js, Tablestore SDK for .NET, or Tablestore SDK for PHP.

The following examples use the Java SDK.

Insert a single row

PutRow supports system-generated version numbers, custom version numbers, and conditional writes.

System-generated version number

Insert a row with 10 attribute columns, each storing one version of data. The system automatically generates the version numbers.

private static void putRow(SyncClient client, String pkValue) {
    // Construct the primary key.
    PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    primaryKeyBuilder.addPrimaryKeyColumn("pk", PrimaryKeyValue.fromString(pkValue));
    PrimaryKey primaryKey = primaryKeyBuilder.build();
    // Specify the name of the table.
    RowPutChange rowPutChange = new RowPutChange("<TABLE_NAME>", primaryKey);

    // Add attribute columns.
    for (int i = 0; i < 10; i++) {
        rowPutChange.addColumn(new Column("Col" + i, ColumnValue.fromLong(i)));
    }

    client.putRow(new PutRowRequest(rowPutChange));
}

Custom version number

Insert a row with 10 attribute columns, each storing three versions of data with custom version numbers.

private static void putRow(SyncClient client, String pkValue) {
    // Construct the primary key.
    PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    primaryKeyBuilder.addPrimaryKeyColumn("pk", PrimaryKeyValue.fromString(pkValue));
    PrimaryKey primaryKey = primaryKeyBuilder.build();
    // Specify the name of the table.
    RowPutChange rowPutChange = new RowPutChange("<TABLE_NAME>", primaryKey);

    // Add attribute columns.
    long ts = System.currentTimeMillis();
    for (int i = 0; i < 10; i++) {
        for (int j = 0; j < 3; j++) {
            rowPutChange.addColumn(new Column("Col" + i, ColumnValue.fromLong(j), ts + j));
        }
    }

    client.putRow(new PutRowRequest(rowPutChange));
}

Row existence condition

Insert a row with 10 attribute columns (three versions each) only when the specified row does not exist.

private static void putRow(SyncClient client, String pkValue) {
    // Construct the primary key.
    PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    primaryKeyBuilder.addPrimaryKeyColumn("pk", PrimaryKeyValue.fromString(pkValue));
    PrimaryKey primaryKey = primaryKeyBuilder.build();
    // Specify the name of the table.
    RowPutChange rowPutChange = new RowPutChange("<TABLE_NAME>", primaryKey);

    // Specify a row existence condition that expects the specified row to not exist.
    rowPutChange.setCondition(new Condition(RowExistenceExpectation.EXPECT_NOT_EXIST));

    // Add attribute columns.
    long ts = System.currentTimeMillis();
    for (int i = 0; i < 10; i++) {
        for (int j = 0; j < 3; j++) {
            rowPutChange.addColumn(new Column("Col" + i, ColumnValue.fromLong(j), ts + j));
        }
    }

    client.putRow(new PutRowRequest(rowPutChange));
}

Row existence and column value conditions

Insert a row with 10 attribute columns (three versions each) when the row exists and the value of Col0 is greater than 100.

private static void putRow(SyncClient client, String pkValue) {
    // Construct the primary key.
    PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    primaryKeyBuilder.addPrimaryKeyColumn("pk", PrimaryKeyValue.fromString(pkValue));
    PrimaryKey primaryKey = primaryKeyBuilder.build();
    // Specify the name of the table.
    RowPutChange rowPutChange = new RowPutChange("<TABLE_NAME>", primaryKey);

    // Specify a row existence condition and a column-based condition that expect the specified row to exist and the value of the Col0 column to be greater than 100.
    Condition condition = new Condition(RowExistenceExpectation.EXPECT_EXIST);
    condition.setColumnCondition(new SingleColumnValueCondition("Col0",
            SingleColumnValueCondition.CompareOperator.GREATER_THAN, ColumnValue.fromLong(100)));
    rowPutChange.setCondition(condition);

    // Add attribute columns.
    long ts = System.currentTimeMillis();
    for (int i = 0; i < 10; i++) {
        for (int j = 0; j < 3; j++) {
            rowPutChange.addColumn(new Column("Col" + i, ColumnValue.fromLong(j), ts + j));
        }
    }

    client.putRow(new PutRowRequest(rowPutChange));
}

Update a single row

UpdateRow supports unconditional updates and conditional updates based on row existence and column values.

Update without conditions

Update multiple columns, delete a specific version of data from a column, and remove a column.

private static void updateRow(SyncClient client, String pkValue) {
    // Construct the primary key.
    PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    primaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME, PrimaryKeyValue.fromString(pkValue));
    PrimaryKey primaryKey = primaryKeyBuilder.build();
    // Specify the name of the table.
    RowUpdateChange rowUpdateChange = new RowUpdateChange("<TABLE_NAME>", primaryKey);

    // Update columns.
    for (int i = 0; i < 10; i++) {
        rowUpdateChange.put(new Column("Col" + i, ColumnValue.fromLong(i)));
    }

    // Delete a specific version of data from a column.
    rowUpdateChange.deleteColumn("Col10", 1465373223000L);

    // Remove a column.
    rowUpdateChange.deleteColumns("Col11");

    client.updateRow(new UpdateRowRequest(rowUpdateChange));
}

Row existence and column value conditions

Update a row when the row exists and the value of Col0 is greater than 100.

private static void updateRow(SyncClient client, String pkValue) {
    // Construct the primary key.
    PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    primaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME, PrimaryKeyValue.fromString(pkValue));
    PrimaryKey primaryKey = primaryKeyBuilder.build();
    // Specify the name of the table.
    RowUpdateChange rowUpdateChange = new RowUpdateChange("<TABLE_NAME>", primaryKey);

    // Specify a row existence condition and a column-based condition that expect the specified row to exist and the value of the Col0 column to be greater than 100.
    Condition condition = new Condition(RowExistenceExpectation.EXPECT_EXIST);
    condition.setColumnCondition(new SingleColumnValueCondition("Col0",
            SingleColumnValueCondition.CompareOperator.GREATER_THAN, ColumnValue.fromLong(100)));
    rowUpdateChange.setCondition(condition);

    // Update columns.
    for (int i = 0; i < 10; i++) {
        rowUpdateChange.put(new Column("Col" + i, ColumnValue.fromLong(i)));
    }

    // Delete a specific version of data from a column.
    rowUpdateChange.deleteColumn("Col10", 1465373223000L);

    // Remove a column.
    rowUpdateChange.deleteColumns("Col11");

    client.updateRow(new UpdateRowRequest(rowUpdateChange));
}

Write multiple rows at once

The following example sends a BatchWriteRow request containing two PutRow operations, one UpdateRow operation, and one DeleteRow operation.

private static void batchWriteRow(SyncClient client) {
    BatchWriteRowRequest batchWriteRowRequest = new BatchWriteRowRequest();

    // Construct rowPutChange1.
    PrimaryKeyBuilder pk1Builder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    pk1Builder.addPrimaryKeyColumn("pk", PrimaryKeyValue.fromString("pk1"));
    // Specify the name of the data table.
    RowPutChange rowPutChange1 = new RowPutChange("<TABLE_NAME>", pk1Builder.build());
    // Add columns.
    for (int i = 0; i < 10; i++) {
        rowPutChange1.addColumn(new Column("Col" + i, ColumnValue.fromLong(i)));
    }
    // Add rowPutChange1 to the code of the batch operation.
    batchWriteRowRequest.addRowChange(rowPutChange1);

    // Construct rowPutChange2.
    PrimaryKeyBuilder pk2Builder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    pk2Builder.addPrimaryKeyColumn("pk", PrimaryKeyValue.fromString("pk2"));
    // Specify the name of the data table.
    RowPutChange rowPutChange2 = new RowPutChange("<TABLE_NAME>", pk2Builder.build());
    // Add columns.
    for (int i = 0; i < 10; i++) {
        rowPutChange2.addColumn(new Column("Col" + i, ColumnValue.fromLong(i)));
    }
    // Add rowPutChange2 to the code of the batch operation.
    batchWriteRowRequest.addRowChange(rowPutChange2);

    // Construct rowUpdateChange.
    PrimaryKeyBuilder pk3Builder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    pk3Builder.addPrimaryKeyColumn("pk", PrimaryKeyValue.fromString("pk3"));
    // Specify the name of the data table.
    RowUpdateChange rowUpdateChange = new RowUpdateChange("<TABLE_NAME>", pk3Builder.build());
    // Add columns.
    for (int i = 0; i < 10; i++) {
        rowUpdateChange.put(new Column("Col" + i, ColumnValue.fromLong(i)));
    }
    // Remove a column.
    rowUpdateChange.deleteColumns("Col10");
    // Add rowUpdateChange to the code of the batch operation.
    batchWriteRowRequest.addRowChange(rowUpdateChange);

    // Construct rowDeleteChange.
    PrimaryKeyBuilder pk4Builder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    pk4Builder.addPrimaryKeyColumn("pk", PrimaryKeyValue.fromString("pk4"));
    // Specify the name of the data table.
    RowDeleteChange rowDeleteChange = new RowDeleteChange("<TABLE_NAME>", pk4Builder.build());
    // Add rowDeleteChange to the code of the batch operation.
    batchWriteRowRequest.addRowChange(rowDeleteChange);

    BatchWriteRowResponse response = client.batchWriteRow(batchWriteRowRequest);

    System.out.println("Whether all operations are successful:" + response.isAllSucceed());
    if (!response.isAllSucceed()) {
        for (BatchWriteRowResponse.RowResult rowResult : response.getFailedRows()) {
            System.out.println("Failed rows:" + batchWriteRowRequest.getRowChange(rowResult.getTableName(), rowResult.getIndex()).getPrimaryKey());
            System.out.println("Cause of failures:" + rowResult.getError());
        }
        /**
         * You can use the createRequestForRetry method to construct another request to retry the operations on failed rows. Only the retry request is constructed here.
         * We recommend that you use the custom retry policy in Tablestore SDKs as the retry method. This feature allows you to retry failed rows after batch operations. After you set the retry policy, you do not need to add retry code to call the operation.
         */
        BatchWriteRowRequest retryRequest = batchWriteRowRequest.createRequestForRetry(response.getFailedRows());
    }
}

Billing

Write operations are charged based on the number of CUs consumed. Metered read and write CUs and reserved read and write CUs are charged separately. The type of instance determines which CU type is consumed.

Note

For more information about instance types and CUs, see Instances and Read and write throughput.

Write CU calculation

OperationFormula
PutRowRounded up: (Size of all primary key columns + Size of inserted attribute columns) / 4 KB
UpdateRowRounded up: (Size of all primary key columns + Size of updated attribute columns) / 4 KB. For column removal operations, the column name length counts as the column size.
DeleteRow (in BatchWriteRow)Rounded up: Size of all primary key columns / 4 KB

Read CU calculation

Read CUs are consumed only when the condition parameter is not set to IGNORE.

OperationFormulaCondition not met
PutRowRounded up: Size of all primary key columns / 4 KBOperation fails. Consumes 1 write CU and 1 read CU.
UpdateRowRounded up: Size of all primary key columns / 4 KBOperation fails. Consumes 1 write CU and 1 read CU.
DeleteRow (in BatchWriteRow)Rounded up: Size of all primary key columns / 4 KBOperation fails. Consumes 1 write CU and 1 read CU.