Read data

更新时间:
复制 MD 格式

Tablestore lets you read data from a table using single-row, batch, and range queries. To read a single row or a batch of rows, you must specify the complete primary keys. To read a range of rows, you must specify a primary key range or a key prefix. You can also configure queries to return only specific attribute columns, a specified number of data versions, data from a specific time range, or data that matches a filter condition.

Query methods

Tablestore provides the GetRow, BatchGetRow, and GetRange interfaces to read data. You can use the appropriate query method based on your scenario.

Important

When you read data from a table that has an auto-increment primary key column, you must provide the complete primary key, including the value of the auto-increment column. For more information, see Auto-increment primary key column. If you do not have the value of the auto-increment primary key column, you can perform a range read on the first primary key column to retrieve the data.

Query method

Description

Scenarios

Read single row data

Call the GetRow interface to read a single row.

Use this method when you know the complete primary key and need to read a small number of rows.

Batch read data

Call the BatchGetRow interface to read multiple rows in a single request or read from multiple tables at once.

A BatchGetRow operation consists of multiple GetRow sub-operations. The process of constructing a sub-operation is the same as when using the GetRow interface.

Use this method when you know the complete primary keys and need to read many rows or read data from multiple tables.

Range read data

Call the GetRange interface to read data within a specified range.

The GetRange operation allows you to read data whose primary key values are in the specified range in a forward or backward direction. You can also specify the number of rows that you want to read. If the range is large and the number of scanned rows or the volume of scanned data exceeds the upper limit, the scan stops, and the rows that are read and information about the primary key of the next row are returned. You can initiate a request to start from the position in which the last operation left off and read the remaining rows based on the information about the primary key of the next row returned by the previous operation.

Use this method when you can define a primary key range or a key prefix.

Important

If you cannot determine a key prefix, you can scan the entire table by setting the primary key range from the virtual point INF_MIN to INF_MAX. This operation consumes a large amount of compute resources. Use it with caution.

Prerequisites

  • An OTSClient instance is initialized. For more information, see Initialize an OTSClient instance.

  • A data table is created and data is written to the data table.

Read single row data

You can call the GetRow operation to read a single row of data. After you call the GetRow operation, one of the following results may be returned:

Interface

"""
Description: Gets a single row of data.
`table_name`: The name of the table.
`primary_key`: The primary key, of type dict.
`columns_to_get`: An optional list of column names to retrieve. If omitted, all columns are retrieved.
`column_filter`: An optional parameter to read only rows that meet specific conditions.
`max_version`: An optional parameter that specifies the maximum number of versions to read.
`time_range`: An optional parameter that specifies a version range or a specific version to read. Set at least one of `max_version` or `time_range`.

Returns: The CapacityUnit consumed, the primary key columns, and the attribute columns.
`consumed`: The consumed CapacityUnit, which is an instance of the `tablestore.metadata.CapacityUnit` class.
`return_row`: The row data, including primary key columns and attribute columns. It is a list, such as `[('PK0',value0), ('PK1',value1)]`.
`next_token`: The starting position for the next read in a wide row scenario. It is a binary-encoded value.

Example:
    primary_key = [('gid',1), ('uid',101)]
    columns_to_get = ['name', 'address', 'age']
    consumed, return_row, next_token = client.get_row('myTable', primary_key, columns_to_get)
"""
def get_row(self, table_name, primary_key, columns_to_get=None,
            column_filter=None, max_version=1, time_range=None,
            start_column=None, end_column=None, token=None,
            transaction_id=None):

Parameters

Parameter

Description

table_name

The table name.

primary_key

The primary key of the row. A 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 match those of the table.

columns_to_get

The set of columns to read. Column names can be primary key columns or attribute columns.

  • If you do not specify columns to return, the entire row is returned.

  • If you specify columns to return, and none of the specified columns exist in a row, the row is not returned (the return value is null). If some of the specified columns exist, the row is returned with only the existing columns.

Note
  • When you query a row, all columns of the row are returned by default. To return only specific columns, use the `columns_to_get` parameter. For example, if you add `col0` and `col1` to `columns_to_get`, only the values of `col0` and `col1` are returned.

  • When `columns_to_get` and `column_filter` are used together, the system first retrieves the columns specified in `columns_to_get` and then applies the filter condition to the returned columns.

column_filter

Use a filter to perform an additional filtering operation on the read results at the server-side. Only data rows that meet the filter conditions are returned. For more information, see Filters.

Note

When `columns_to_get` and `column_filter` are used together, the system first retrieves the columns specified in `columns_to_get` and then applies the filter condition to the returned columns.

max_version

The maximum number of versions to read.

Important

Set at least one of `max_version` or `time_range`.

  • If you set only `max_version`, the specified number of latest versions are returned.

  • If you set only `time_range`, all data within the specified range or at the specified version is returned.

  • If you set both `max_version` and `time_range`, the specified number of latest versions within the version range are returned.

time_range

Reads data of a specific version number or within a version number range. For more information, see TimeRange.

Important

Set at least one of `max_version` or `time_range`.

  • If you set only `max_version`, the specified number of latest versions are returned.

  • If you set only `time_range`, all data within the specified range or at the specified version is returned.

  • If you set both `max_version` and `time_range`, the specified number of latest versions within the version range are returned.

  • To query data within a range, set `start_time` and `end_time`. These parameters represent the start and end timestamps. The range is left-closed and right-open: [start_time, end_time).

  • To query data of a specific version, set `specific_time`. This parameter represents a specific timestamp.

Set either `specific_time` or the [start_time, end_time) range.

The timestamp is in milliseconds. The minimum value is 0, and the maximum value is INT64.MAX.

transaction_id

The local transaction ID. This parameter is required when you use the local transaction feature to read data.

Example

The following example shows how to read a single row from a table.

# The first primary key column is 'gid' with an integer value of 1. The second is 'uid' with an integer value of 101.
primary_key = [('gid', 1), ('uid', 101)]

# The attribute columns to return are 'name', 'growth', and 'type'. If columns_to_get is [], all attribute columns are returned.
columns_to_get = ['name', 'growth', 'type']

# Set a filter to add column conditions. The filter condition is that the value of the 'growth' column is not equal to 0.9 AND the value of the 'name' column is equal to 'Hangzhou'.
cond = CompositeColumnCondition(LogicalOperator.AND)
cond.add_sub_condition(SingleColumnCondition("growth", 0.9, ComparatorType.NOT_EQUAL))
cond.add_sub_condition(SingleColumnCondition("name", 'Hangzhou', ComparatorType.EQUAL))

try:
    # Call the get_row interface to query data.
    # Configure the table name. The last parameter value, 1, indicates that only one version needs to be returned.
    consumed, return_row, next_token = client.get_row('<table_name>', primary_key, columns_to_get, cond, 1)
    print('Read succeed, consume %s read cu.' % consumed.read)
    print('Value of primary key: %s' % return_row.primary_key)
    print('Value of attribute: %s' % return_row.attribute_columns)
    for att in return_row.attribute_columns:
        # Print the key, value, and timestamp of each column.
        print('name:%s\tvalue:%s\ttimestamp:%d' % (att[0], att[1], att[2]))
# A client exception occurs, typically due to a parameter error or a network issue.
except OTSClientError as e:
    print('get row failed, http_status:%d, error_message:%s' % (e.get_http_status(), e.get_error_message()))
# A server-side exception occurs, typically due to a parameter error or a throttling error.
except OTSServiceError as e:
    print('get row failed, http_status:%d, error_code:%s, error_message:%s, request_id:%s' % (e.get_http_status(), e.get_error_code(), e.get_error_message(), e.get_request_id()))

For the complete sample code, see GetRow@GitHub.

Batch read data

You can call the BatchGetRow operation to read multiple rows of data from one or more tables at the same time. The BatchGetRow operation consists of multiple GetRow operations. When you call the BatchGetRow operation, the process of constructing each GetRow operation is the same as the process of constructing the GetRow operation when you call the GetRow operation.

If you call the BatchGetRow operation, each GetRow operation is separately performed. Tablestore separately returns the response to each GetRow operation.

Notes

  • A batch read operation may fail for some rows. The error messages for the failed rows are included in the returned BatchGetRowResponse, but no exception is thrown. Therefore, when you call the BatchGetRow operation, you must check the return value to determine whether the operation is successful for each row.

  • The same parameter conditions apply to all rows in a batch read operation. For example, if you set ColumnsToGet=[colA], only the colA column is read for all rows.

  • A single BatchGetRow operation can read a maximum of 100 rows.

Interface

"""
Description: Batch gets multiple rows of data.
request = BatchGetRowRequest()
request.add(TableInBatchGetRowItem(myTable0, primary_keys, column_to_get=None, column_filter=None))
request.add(TableInBatchGetRowItem(myTable1, primary_keys, column_to_get=None, column_filter=None))
request.add(TableInBatchGetRowItem(myTable2, primary_keys, column_to_get=None, column_filter=None))
request.add(TableInBatchGetRowItem(myTable3, primary_keys, column_to_get=None, column_filter=None))
response = client.batch_get_row(request)
`response` is the returned result, of type tablestore.metadata.BatchGetRowResponse.
"""
def batch_get_row(self, request):                    
  

Parameters

For more information, see Parameters for reading a single row.

Example

The following example shows how to read three rows from multiple tables in a single batch operation.

# Specify the columns to return.
columns_to_get = ['name', 'mobile', 'address', 'age']
# Read 3 rows.
rows_to_get = []
for i in range(0, 3):
    primary_key = [('gid', i), ('uid', i + 1)]
    rows_to_get.append(primary_key)

# Set a filter to add column conditions. The filter condition is that the value of the 'name' column is 'John' AND the value of the 'address' column is 'China'.
cond = CompositeColumnCondition(LogicalOperator.AND)
cond.add_sub_condition(SingleColumnCondition("name", "John", ComparatorType.EQUAL))
cond.add_sub_condition(SingleColumnCondition("address", 'China', ComparatorType.EQUAL))

# Construct a batch read request.
request = BatchGetRowRequest()

# Add the rows to be read from the specified table. The last parameter, 1, indicates that the latest version is read.
request.add(TableInBatchGetRowItem('<table_name1>', rows_to_get, columns_to_get, cond, 1))

# Add the rows to be read from another table.
request.add(TableInBatchGetRowItem('<table_name2>', rows_to_get, columns_to_get, cond, 1))

try:
    result = client.batch_get_row(request)
    print('Result status: %s' % (result.is_all_succeed()))

    table_result_0 = result.get_result_by_table('<table_name1>')
    table_result_1 = result.get_result_by_table('<table_name2>')
    print('Check first table\'s result:')
    for item in table_result_0:
        if item.is_ok:
            print('Read succeed, PrimaryKey: %s, Attributes: %s' % (item.row.primary_key, item.row.attribute_columns))
        else:
            print('Read failed, error code: %s, error message: %s' % (item.error_code, item.error_message))
    print('Check second table\'s result:')
    for item in table_result_1:
        if item.is_ok:
            print('Read succeed, PrimaryKey: %s, Attributes: %s' % (item.row.primary_key, item.row.attribute_columns))
        else:
            print('Read failed, error code: %s, error message: %s' % (item.error_code, item.error_message))
# A client exception occurs, typically due to a parameter error or a network issue.
except OTSClientError as e:
    print('get row failed, http_status:%d, error_message:%s' % (e.get_http_status(), e.get_error_message()))
# A server-side exception occurs, typically due to a parameter error or a throttling error.
except OTSServiceError as e:
    print('get row failed, http_status:%d, error_code:%s, error_message:%s, request_id:%s' % (e.get_http_status(), e.get_error_code(), e.get_error_message(), e.get_request_id()))

For the complete sample code, see BatchGetRow@GitHub.

Range read data

You can call the GetRange operation to read data whose primary key values are in the specified range.

The GetRange operation allows you to read data whose primary key values are in the specified range in a forward or backward direction. You can also specify the number of rows that you want to read. If the range is large and the number of scanned rows or the volume of scanned data exceeds the upper limit, the scan stops, and the rows that are read and information about the primary key of the next row are returned. You can initiate a request to start from the position in which the last operation left off and read the remaining rows based on the information about the primary key of the next row returned by the previous operation.

Note

In Tablestore tables, all rows are sorted by primary key. The primary key of a table sequentially consists of all primary key columns. Therefore, the rows are not sorted based on a specific primary key column.

Notes

The GetRange operation follows the leftmost matching principle. Tablestore compares values in sequence from the first primary key column to the last primary key column to read data whose primary key values are in the specified range. For example, the primary key of a data table consists of the following primary key columns: PK1, PK2, and PK3. When data is read, Tablestore first determines whether the PK1 value of a row is in the range that is specified for the first primary key column. If the PK1 value of a row is in the range, Tablestore stops determining whether the values of other primary key columns of the row are in the ranges that are specified for each primary key column and returns the row. If the PK1 value of a row is not in the range, Tablestore continues to determine whether the values of other primary key columns of the row are in the ranges that are specified for each primary key column in the same manner as PK1.For more information about the principles of range queries, seeGetRangeRange Query Details.

  • The amount of scanned data reaches 4 MB.

  • The number of scanned rows reaches 5,000.

  • The number of returned rows reaches the upper limit.

  • The read throughput is insufficient to read the next row of data because all reserved read throughput is consumed.

When you use GetRange to scan a large volume of data, Tablestore performs only one scan per request. The scan stops if the number of rows exceeds 5,000 or the data size exceeds 4 MB. Data that exceeds these limits is not returned. You must use pagination to retrieve the subsequent data.

Interface

"""
Description: Gets multiple rows of data based on a range condition.
`table_name`: The name of the table.
`direction`: The read direction for the range query. It is a string and can be 'FORWARD' or 'BACKWARD'.
`inclusive_start_primary_key`: The start primary key of the range (inclusive).
`exclusive_end_primary_key`: The end primary key of the range (exclusive).
`columns_to_get`: An optional list of column names to retrieve. If omitted, all columns are retrieved.
`limit`: An optional parameter that specifies the maximum number of rows to read. If omitted, there is no limit.
`column_filter`: An optional parameter to read only rows that meet specific conditions.
`max_version`: An optional parameter that specifies the maximum number of versions to return. Set at least one of `max_version` or `time_range`.
`time_range`: An optional parameter that specifies the version range to return. Set at least one of `max_version` or `time_range`.
`start_column`: An optional parameter for wide row reads. It specifies the starting column for the current read.
`end_column`: An optional parameter for wide row reads. It specifies the ending column for the current read.
`token`: An optional parameter for wide row reads. It specifies the starting column position for the current read. The content is binary-encoded and comes from the result of the previous request.

Returns: A list of results that meet the conditions.
`consumed`: The CapacityUnit consumed by the operation, which is an instance of the `tablestore.metadata.CapacityUnit` class.
`next_start_primary_key`: The primary key of the starting point for the next get_range operation. It is of type dict.
`row_list`: A list of row data returned by the operation, in the format: [Row, ...].  
"""
def get_range(self, table_name, direction,
             inclusive_start_primary_key,
             exclusive_end_primary_key,
             columns_to_get=None,
             limit=None,
             column_filter=None,
             max_version=None,
             time_range=None,
             start_column=None,
             end_column=None,
             token=None):

Parameters

Parameter

Description

table_name

The table name.

direction

The read direction.

  • If the value is FORWARD, the start primary key must be less than the end primary key. The returned rows are sorted by primary key in ascending order.

  • If the value is BACKWARD, the start primary key must be greater than the end primary key. The returned rows are sorted by primary key in descending order.

Assume a table has two primary keys, A and B, where A is less than B. If you perform a forward read on the range [A, B), rows with primary keys greater than or equal to A and less than B are returned in order from A to B. If you perform a backward read on the range [B, A), rows with primary keys greater than A and less than or equal to B are returned in order from B to A.

inclusive_start_primary_key

The start and end primary keys for the range read. The start and end primary keys must be valid primary keys or virtual points composed of INF_MIN and INF_MAX types. The number of columns in a virtual point must be the same as the number of primary key columns.

INF_MIN represents negative infinity and is smaller than any other value. INF_MAX represents positive infinity and is larger than any other value.

  • `inclusive_start_primary_key` is the start primary key. If a row with this key exists, it is included in the result.

  • `exclusive_end_primary_key` is the end primary key. A row with this key is not included in the result, regardless of whether it exists.

Rows in a table are sorted by primary key in ascending order. The read range is a left-closed, right-open interval. For a forward read, all rows with primary keys greater than or equal to the start primary key and less than the end primary key are returned.

exclusive_end_primary_key

limit

The maximum number of rows to return. This value must be greater than 0.

Tablestore returns the specified maximum number of rows in forward or backward order and then ends the operation, even if there is more data in the interval. In this case, you can use the `next_start_primary_key` from the result to continue reading from the last position in the next request.

columns_to_get

The set of columns to read. Column names can be primary key columns or attribute columns.

  • If you do not specify columns to return, the entire row is returned.

  • If you specify columns to return, and none of the specified columns exist in a row, the row is not returned (the return value is null). If some of the specified columns exist, the row is returned with only the existing columns.

Note
  • When you query a row, all columns of the row are returned by default. To return only specific columns, use the `columns_to_get` parameter. For example, if you add `col0` and `col1` to `columns_to_get`, only the values of `col0` and `col1` are returned.

  • If a row's primary key is within the read range, but the row does not contain any of the specified columns to return, the row is not included in the result.

  • When `columns_to_get` and `column_filter` are used together, the system first retrieves the columns specified in `columns_to_get` and then applies the filter condition to the returned columns.

max_version

The maximum number of versions to read.

Important

Set at least one of `max_version` or `time_range`.

  • If you set only `max_version`, the specified number of latest versions are returned.

  • If you set only `time_range`, all data within the specified range or at the specified version is returned.

  • If you set both `max_version` and `time_range`, the specified number of latest versions within the version range are returned.

time_range

Reads data of a specific version number or within a version number range. For more information, see TimeRange.

Important

Set at least one of `max_version` or `time_range`.

  • If you set only `max_version`, the specified number of latest versions are returned.

  • If you set only `time_range`, all data within the specified range or at the specified version is returned.

  • If you set both `max_version` and `time_range`, the specified number of latest versions within the version range are returned.

  • To query data within a range, set `start_time` and `end_time`. These parameters represent the start and end timestamps. The range is left-closed and right-open: [start_time, end_time).

  • To query data of a specific version, set `specific_time`. This parameter represents a specific timestamp.

Set either `specific_time` or the [start_time, end_time) range.

The timestamp is in milliseconds. The minimum value is 0, and the maximum value is INT64.MAX.

column_filter

Use a filter to perform an additional filtering operation on the read results at the server-side. Only data rows that meet the filter conditions are returned. For more information, see Filters.

Note

When `columns_to_get` and `column_filter` are used together, the system first retrieves the columns specified in `columns_to_get` and then applies the filter condition to the returned columns.

next_start_primary_key

Check `next_start_primary_key` in the return result to determine if all data has been read.

  • If `next_start_primary_key` in the result is not empty, you can use this return value as the starting point for the next GetRange operation to continue reading data.

  • If `next_start_primary_key` in the result is empty, all data within the read range has been returned.

Example

The following example shows how to perform a forward read on a range. The range is defined by the first primary key column, and the second primary key column spans from the minimum value (INF_MIN) to the maximum value (INF_MAX). The code checks whether `nextStartPrimaryKey` is null to ensure that all data within the range is read.

# Set the start primary key for the range read.
inclusive_start_primary_key = [('gid', 1), ('uid', INF_MIN)]

# Set the end primary key for the range read.
exclusive_end_primary_key = [('gid', 5), ('uid', INF_MAX)]

# Query all columns.
columns_to_get = []

# Return a maximum of 90 rows at a time. If there are 100 results in total and you set limit=90 for the first query, the first query returns a maximum of 90 results and a minimum of 0 results, but next_start_primary_key will not be None.
limit = 90

# Set a filter to add column conditions. The filter condition is that the value of the 'address' column is 'China' AND the value of the 'age' column is less than 50.
cond = CompositeColumnCondition(LogicalOperator.AND)
# If a row does not contain a specified column, configure the pass_if_missing parameter to determine whether the row meets the filter condition.
# If you do not set pass_if_missing or set it to True, a row is considered to meet the filter condition if it does not contain the column.
# If you set pass_if_missing to False, a row is considered not to meet the filter condition if it does not contain the column.
cond.add_sub_condition(SingleColumnCondition("address", 'China', ComparatorType.EQUAL, pass_if_missing = False))
cond.add_sub_condition(SingleColumnCondition("age", 50, ComparatorType.LESS_THAN, pass_if_missing = False))

try:
    # Call the get_range interface.
    consumed, next_start_primary_key, row_list, next_token = client.get_range(
        '<table_name>', Direction.FORWARD,
        inclusive_start_primary_key, exclusive_end_primary_key,
        columns_to_get,
        limit,
        column_filter=cond,
        max_version=1,
        time_range = (1557125059000, 1557129059000)  # start_time is greater than or equal to 1557125059000, and end_time is less than 1557129059000.
    )

    all_rows = []
    all_rows.extend(row_list)

    # If next_start_primary_key is not empty, continue to read data.
    while next_start_primary_key is not None:
        inclusive_start_primary_key = next_start_primary_key
        consumed, next_start_primary_key, row_list, next_token = client.get_range(
            '<table_name>', Direction.FORWARD,
            inclusive_start_primary_key, exclusive_end_primary_key,
            columns_to_get, limit,
            column_filter=cond,
            max_version=1
        )
        all_rows.extend(row_list)

    # Print the primary key and attribute columns.
    for row in all_rows:
        print(row.primary_key, row.attribute_columns)
    print('Total rows: ', len(all_rows))
# A client exception occurs, typically due to a parameter error or a network issue.
except OTSClientError as e:
    print('get row failed, http_status:%d, error_message:%s' % (e.get_http_status(), e.get_error_message()))
# A server-side exception occurs, typically due to a parameter error or a throttling error.
except OTSServiceError as e:
    print('get row failed, http_status:%d, error_code:%s, error_message:%s, request_id:%s' % (e.get_http_status(), e.get_error_code(), e.get_error_message(), e.get_request_id()))

For the complete sample code, see GetRange@GitHub.

FAQ

References

  • To accelerate data queries, you can use secondary indexes or search indexes. For more information, see Secondary index or Search index.

  • To visualize data in a table, you can integrate with tools such as DataV or Grafana. For more information, see Data visualization.

  • To download table data to a local file, you can use DataX or the Tablestore command-line interface (CLI). For more information, see Download to a local file.

  • To compute and analyze data in a table, you can use Tablestore SQL queries. For more information, see SQL query.

    Note

    You can also use compute engines such as MaxCompute, Spark, Hive, Hadoop MR, Function Compute, or Flink to compute and analyze table data. For more information, see Compute and analyze data.