全部產品
Search
文件中心

Tablestore:讀取資料

更新時間:Oct 11, 2024

Table Store提供了單行讀取、批量讀取和範圍讀取的查詢方式用於讀取資料表中資料。當要讀取單行資料或者批量讀取表中資料時,您必須指定行的完整主鍵;當要範圍讀取表中資料時,您需要指定完整主鍵範圍或者主鍵首碼。讀取資料時支援配置返回指定屬性列、指定資料版本個數、指定資料時間範圍或者滿足過濾條件的資料。

查詢方式

Tablestore提供的資料讀取介面包括GetRow、BatchGetRow和GetRange。讀取資料時,請根據實際查詢情境使用相應查詢方式。

重要

當要讀取帶有自增主鍵列的表資料時,請確保已擷取到包含自增主鍵列值在內的完整主鍵。更多資訊,請參見主鍵列自增。如果未記錄自增主鍵列的值,您可以使用範圍讀取資料按照第一個主鍵列確定範圍讀取資料。

查詢方式

說明

適用情境

讀取單行資料

調用GetRow介面讀取一行資料。

適用於能確定完整主鍵且要讀取行數較少的情境。

批量讀取資料

調用BatchGetRow介面一次請求讀取多行資料或者一次對多張表進行讀取。

BatchGetRow操作由多個GetRow子操作組成,構造子操作的過程與使用GetRow介面時相同。

適用於能確定完整主鍵,且要讀取行數較多或者要讀取多個表中資料的情境。

範圍讀取資料

調用GetRange介面讀取一個範圍內的資料。

GetRange操作支援按照確定範圍進行正序讀取和逆序讀取,可以設定要讀取的行數。如果範圍較大,已掃描的行數或者資料量超過一定限制,會停止掃描,並返回已擷取的行和下一個主鍵資訊。您可以根據返回的下一個主鍵資訊,繼續發起請求,擷取範圍內剩餘的行。

適用於能確定完整主鍵範圍或者主鍵首碼的情境。

重要

如果不能確定主鍵首碼,您也可以通過設定完整主鍵範圍均為虛擬點INF_MIN和INF_MAX進行全表資料掃描,但是執行此操作會消耗較多計算資源,請謹慎使用。

前提條件

  • 已初始化Client。具體操作,請參見初始化OTSClient

  • 已建立資料表並寫入資料。

讀取單行資料

調用GetRow介面讀取一行資料。讀取的結果可能有如下兩種:

  • 如果該行存在,則返回該行的各主鍵列以及屬性列。

  • 如果該行不存在,則返回中不包含行,並且不會報錯。

介面

"""
說明:擷取一行資料。
``table_name``是對應的表名。
``primary_key``是主鍵,類型為dict。
``columns_to_get``是選擇性參數,表示要擷取的列的名稱列表,類型為list;如果不填,表示擷取所有列。
``column_filter``是選擇性參數,表示讀取指定條件的行
``max_version``是選擇性參數,表示最多讀取的版本數
``time_range``是選擇性參數,表示讀取額版本範圍或特定版本,和max_version至少存在一個
返回:本次操作消耗的CapacityUnit、主鍵列和屬性列。
``consumed``表示消耗的CapacityUnit,是tablestore.metadata.CapacityUnit類的執行個體。
``return_row``表示行資料,包括主鍵列和屬性列,類型都為list,如:[('PK0',value0), ('PK1',value1)]。
``next_token``表示寬行讀取時下一次讀取的位置,編碼的二進位。
樣本:
    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):

參數

參數

說明

table_name

資料表名稱。

primary_key

行的主鍵。主鍵包括主鍵列名、主鍵類型和主索引值。

重要

設定的主鍵個數和類型必須和資料表的主鍵個數和類型一致。

columns_to_get

讀取的列集合,列名可以是主鍵列或屬性列。

  • 如果不設定返回的列名,則返回整行資料。

  • 如果設定了返回的列名,當某行中指定的列均不存在時,則不返回該行,即傳回值為null;當某行中存在部分指定的列時,則返回該行且只返回存在的列。

說明
  • 查詢一行資料時,預設返回此行所有列的資料。如果需要只返回特定列,可以通過設定columns_to_get參數限制。如果將col0和col1加入到columns_to_get中,則只返回col0和col1列的值。

  • 當columns_to_get和column_filter同時使用時,執行順序是先擷取columns_to_get指定的列,再在返回的列中進行條件過濾。

column_filter

使用過濾器,在服務端對讀取結果再進行一次過濾,只返回符合過濾器中條件的資料行。更多資訊,請參見過濾器

說明

當columns_to_get和column_filter同時使用時,執行順序是先擷取columns_to_get指定的列,再在返回的列中進行條件過濾。

max_version

最多讀取的版本數。

重要

max_version與time_range必須至少設定一個。

  • 如果僅設定max_version,則最多返回所有版本中從新到舊指定數量版本的資料。

  • 如果僅設定time_range,則返回該範圍內所有資料或指定版本資料。

  • 如果同時設定max_version和time_range,則最多返回版本號碼範圍內從新到舊指定數量版本的資料。

time_range

讀取版本號碼範圍或特定版本號碼的資料。更多資訊,請參見TimeRange

重要

max_version與time_range必須至少設定一個。

  • 如果僅設定max_version,則最多返回所有版本中從新到舊指定數量版本的資料。

  • 如果僅設定time_range,則返回該範圍內所有資料或指定版本資料。

  • 如果同時設定max_version和time_range,則最多返回版本號碼範圍內從新到舊指定數量版本的資料。

  • 如果要查詢一個範圍的資料,則需要設定start_time和end_time。start_time和end_time分別表示起始時間戳記和結束時間戳記,範圍為前閉後開區間,即[start_time, end_time)

  • 如果要查詢特定版本號碼的資料,則需要設定specific_time。specific_time表示特定的時間戳記。

specific_time和[start_time, end_time)中只需要設定一個。

時間戳記的單位為毫秒,最小值為0,最大值為INT64.MAX

transaction_id

局部事務ID。使用局部事務功能讀取資料時必須設定此參數。

樣本

以下樣本用於讀取表中一行資料。

# 主鍵的第一列是gid,值是整數1,第二列是uid,值是整數101。
primary_key = [('gid', 1), ('uid', 101)]

# 需要返回的屬性列name、growth、type。如果columns_to_get為[],則返回所有屬性列。
columns_to_get = ['name', 'growth', 'type']

# 設定過濾器,增加列條件。過濾條件為growth列值不等於0.9且name列值等於'杭州'。
cond = CompositeColumnCondition(LogicalOperator.AND)
cond.add_sub_condition(SingleColumnCondition("growth", 0.9, ComparatorType.NOT_EQUAL))
cond.add_sub_condition(SingleColumnCondition("name", '杭州', ComparatorType.EQUAL))

try:
    # 調用get_row介面查詢資料。
    # 配置資料表名稱,最後一個參數值1表示只需要返回一個版本的值。
    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:
        # 列印每一列的key、value和version值。
        print('name:%s\tvalue:%s\ttimestamp:%d' % (att[0], att[1], att[2]))
# 用戶端異常,一般為參數錯誤或者網路異常。
except OTSClientError as e:
    print('get row failed, http_status:%d, error_message:%s' % (e.get_http_status(), e.get_error_message()))
# 服務端異常,一般為參數錯誤或者流控錯誤。
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()))

詳細代碼請參見GetRow@GitHub

批量讀取資料

調用BatchGetRow介面一次請求讀取多行資料,也支援一次對多張表進行讀取。BatchGetRow由多個GetRow子操作組成。構造子操作的過程與使用GetRow介面時相同。

BatchGetRow的各個子操作獨立執行,Tablestore會分別返回各個子操作的執行結果。

注意事項

  • 由於批量讀取可能存在部分行失敗的情況,失敗行的錯誤資訊在返回的BatchGetRowResponse中,但並不拋出異常。因此調用BatchGetRow介面時,需要檢查傳回值,判斷每行的狀態是否成功。

  • 批量讀取的所有行採用相同的參數條件,例如ColumnsToGet=[colA],表示要讀取的所有行都唯讀取colA列。

  • BatchGetRow操作單次支援讀取的最大行數為100行。

介面

"""
說明:批量擷取多行資料。
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``為返回的結果,類型為tablestore.metadata.BatchGetRowResponse。
"""
def batch_get_row(self, request):                    
  

參數

更多資訊,請參見讀取單行資料參數

樣本

以下樣本用於批量一次讀取多個表中的3行資料。

# 設定需要返回的列。
columns_to_get = ['name', 'mobile', 'address', 'age']
# 讀取3行。
rows_to_get = []
for i in range(0, 3):
    primary_key = [('gid', i), ('uid', i + 1)]
    rows_to_get.append(primary_key)

# 設定過濾器,增加列條件。過濾條件為name列值等於'John'且address列值等於'China'。
cond = CompositeColumnCondition(LogicalOperator.AND)
cond.add_sub_condition(SingleColumnCondition("name", "John", ComparatorType.EQUAL))
cond.add_sub_condition(SingleColumnCondition("address", 'China', ComparatorType.EQUAL))

# 構造批量讀請求。
request = BatchGetRowRequest()

# 增加指定表中需要讀取的行,最後一個參數1表示讀取最新的一個版本。
request.add(TableInBatchGetRowItem('<table_name1>', rows_to_get, columns_to_get, cond, 1))

# 增加另一個表中需要讀取的行。
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))
# 用戶端異常,一般為參數錯誤或者網路異常。
except OTSClientError as e:
    print('get row failed, http_status:%d, error_message:%s' % (e.get_http_status(), e.get_error_message()))
# 服務端異常,一般為參數錯誤或者流控錯誤。
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()))

詳細代碼請參見BatchGetRow@GitHub

範圍讀取資料

調用GetRange介面讀取一個範圍內的資料。

GetRange操作支援按照確定範圍進行正序讀取和逆序讀取,可以設定要讀取的行數。如果範圍較大,已掃描的行數或者資料量超過一定限制,會停止掃描,並返回已擷取的行和下一個主鍵資訊。您可以根據返回的下一個主鍵資訊,繼續發起請求,擷取範圍內剩餘的行。

說明

Tablestore表中的行都是按照主鍵排序的,而主鍵是由全部主鍵列按照順序組成的,所以不能理解為Tablestore會按照某列主鍵排序,這是常見的誤區。

注意事項

GetRange操作遵循最左匹配原則,讀取資料時,依次比較第一主鍵列到第四主鍵列。例如表的主鍵包括PK1、PK2、PK3三個主鍵列,讀取資料時,優先比較PK1是否在開始主鍵與結束主鍵的範圍內,如果PK1在設定的主鍵範圍內,則不會再比較其他的主鍵,返回在PK1主鍵範圍內的資料;如果PK1在設定的主鍵邊界上,則繼續比較PK2是否在開始主鍵與結束主鍵的範圍內,以此類推。

GetRange操作可能在如下情況停止執行並返回資料。

  • 掃描的行資料大小之和達到4 MB。

  • 掃描的行數等於5000。

  • 返回的行數等於最大返回行數。

  • 當前剩餘的預留讀輸送量已全部使用,餘量不足以讀取下一條資料。

當使用GetRange掃描的資料量較大時,Tablestore每次請求僅會掃描一次(行數大於5000或者大小大於4 MB停止掃描),超過限制的資料不會繼續返回,需要通過翻頁繼續擷取後面的資料。

介面

"""
說明:根據範圍條件擷取多行資料。
``table_name``是資料表名稱。
``direction``表示範圍讀取的讀取方向,字串格式,取值包括'FORWARD'和'BACKWARD'。
``inclusive_start_primary_key``表示範圍的起始主鍵(在範圍內)。
``exclusive_end_primary_key``表示範圍的結束主鍵(不在範圍內)。
``columns_to_get``是選擇性參數,表示要擷取的列的名稱列表,類型為list;如果不填,表示擷取所有列。
``limit``是選擇性參數,表示最多讀取多少行;如果不填,則沒有限制。
``column_filter``是選擇性參數,表示讀取指定條件的行。
``max_version``是選擇性參數,表示返回的最大版本數目,max_version與time_range必須至少存在一個。
``time_range``是選擇性參數,表示返回的版本的範圍,max_version與time_range必須至少存在一個。
``start_column``是選擇性參數,用於寬行讀取,表示本次讀取的起始列。
``end_column``是選擇性參數,用於寬行讀取,表示本次讀取的結束列。
``token``是選擇性參數,用於寬行讀取,表示本次讀取的起始列位置,內容被二進位編碼,來源於上次請求的返回結果中。

返回:合格結果清單。
``consumed``表示本次操作消耗的CapacityUnit,是tablestore.metadata.CapacityUnit類的執行個體。
``next_start_primary_key``表示下次get_range操作的起始點的主健列,類型為dict。
``row_list``表示本次操作返回的行資料列表,格式為:[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):

參數

參數

說明

table_name

資料表名稱。

direction

讀取方向。

  • 如果值為正序(FORWARD),則起始主鍵必須小於結束主鍵,返回的行按照主鍵由小到大的順序進行排列。

  • 如果值為逆序(BACKWARD),則起始主鍵必須大於結束主鍵,返回的行按照主鍵由大到小的順序進行排列。

假設同一表中有兩個主鍵A和B,A小於B,如果正序讀取[A, B),則按從A到B的順序返回主鍵大於等於A且小於B的行資料;如果逆序讀取[B, A),則按從B到A的順序返回大於A且小於等於B的行資料。

inclusive_start_primary_key

本次範圍讀的起始主鍵和結束主鍵,起始主鍵和結束主鍵需要是有效主鍵或者是由INF_MIN和INF_MAX類型組成的虛擬點,虛擬點的列數必須與主鍵相同。

其中INF_MIN表示無限小,任何類型的值都比它大;INF_MAX表示無限大,任何類型的值都比它小。

  • inclusive_start_primary_key表示起始主鍵,如果該行存在,則返回結果中一定會包含此行。

  • exclusive_end_primary_key表示結束主鍵,無論該行是否存在,返回結果中都不會包含此行。

資料表中的行按主鍵從小到大排序,讀取範圍是一個左閉右開的區間,正序讀取時,返回的是大於等於起始主鍵且小於結束主鍵的所有的行。

exclusive_end_primary_key

limit

資料的最大返回行數,此值必須大於 0。

Tablestore按照正序或者逆序返回指定的最大返回行數後即結束該操作的執行,即使該區間內仍有未返回的資料。此時可以通過返回結果中的next_start_primary_key記錄本次讀取到的位置,用於下一次讀取。

columns_to_get

讀取的列集合,列名可以是主鍵列或屬性列。

  • 如果不設定返回的列名,則返回整行資料。

  • 如果設定了返回的列名,當某行中指定的列均不存在時,則不返回該行,即傳回值為null;當某行中存在部分指定的列時,則返回該行且只返回存在的列。

說明
  • 查詢一行資料時,預設返回此行所有列的資料。如果需要只返回特定列,可以通過設定columns_to_get參數限制。如果將col0和col1加入到columns_to_get中,則只返回col0和col1列的值。

  • 如果某行資料的主鍵屬於讀取範圍,但是該行資料不包含指定返回的列,那麼返回結果中不包含該行資料。

  • 當columns_to_get和column_filter同時使用時,執行順序是先擷取columns_to_get指定的列,再在返回的列中進行條件過濾。

max_version

最多讀取的版本數。

重要

max_version與time_range必須至少設定一個。

  • 如果僅設定max_version,則最多返回所有版本中從新到舊指定數量版本的資料。

  • 如果僅設定time_range,則返回該範圍內所有資料或指定版本資料。

  • 如果同時設定max_version和time_range,則最多返回版本號碼範圍內從新到舊指定數量版本的資料。

time_range

讀取版本號碼範圍或特定版本號碼的資料。更多資訊,請參見TimeRange

重要

max_version與time_range必須至少設定一個。

  • 如果僅設定max_version,則最多返回所有版本中從新到舊指定數量版本的資料。

  • 如果僅設定time_range,則返回該範圍內所有資料或指定版本資料。

  • 如果同時設定max_version和time_range,則最多返回版本號碼範圍內從新到舊指定數量版本的資料。

  • 如果要查詢一個範圍的資料,則需要設定start_time和end_time。start_time和end_time分別表示起始時間戳記和結束時間戳記,範圍為前閉後開區間,即[start_time, end_time)

  • 如果要查詢特定版本號碼的資料,則需要設定specific_time。specific_time表示特定的時間戳記。

specific_time和[start_time, end_time)中只需要設定一個。

時間戳記的單位為毫秒,最小值為0,最大值為INT64.MAX

column_filter

使用過濾器,在服務端對讀取結果再進行一次過濾,只返回符合過濾器中條件的資料行。更多資訊,請參見過濾器

說明

當columns_to_get和column_filter同時使用時,執行順序是先擷取columns_to_get指定的列,再在返回的列中進行條件過濾。

next_start_primary_key

根據返回結果中的next_start_primary_key判斷資料是否全部讀取。

  • 當返回結果中next_start_primary_key不為空白時,可以使用此傳回值作為下一次GetRange操作的起始點繼續讀取資料。

  • 當返回結果中next_start_primary_key為空白時,表示讀取範圍內的資料全部返回。

樣本

以下樣本用於按照第一個主鍵列確定範圍、第二個主鍵列從最小值(INF_MIN)到最大值(INF_MAX)進行正序讀取,判斷nextStartPrimaryKey是否為null,讀取完範圍內的全部資料。

# 設定範圍讀的起始主鍵。
inclusive_start_primary_key = [('gid', 1), ('uid', INF_MIN)]

# 設定範圍讀的結束主鍵。
exclusive_end_primary_key = [('gid', 5), ('uid', INF_MAX)]

# 查詢所有列。
columns_to_get = []

# 每次最多返回90行,如果總共有100個結果,首次查詢時指定limit=90,則第一次最多返回90,最少可能返回0個結果,但是next_start_primary_key不為None。
limit = 90

# 設定過濾器,增加列條件。過濾條件為address列值等於'China'且age列值小於50。
cond = CompositeColumnCondition(LogicalOperator.AND)
# 如果某行不存在對應列時,您需要配置pass_if_missing參數來確定該行是否滿足過濾條件。
# 當不設定pass_if_missing或者設定pass_if_missing為True時,表示當某行不存在該列時,該行滿足過濾條件。
# 當設定pass_if_missing為False時,表示當某行不存在該列時,該行不滿足過濾條件。
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:
    # 調用get_range介面。
    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大於等於1557125059000,end_time小於1557129059000。
    )

    all_rows = []
    all_rows.extend(row_list)

    # 當next_start_primary_key不為空白時,則繼續讀取資料。
    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)

    # 列印主鍵和屬性列。
    for row in all_rows:
        print(row.primary_key, row.attribute_columns)
    print('Total rows: ', len(all_rows))
# 用戶端異常,一般為參數錯誤或者網路異常。
except OTSClientError as e:
    print('get row failed, http_status:%d, error_message:%s' % (e.get_http_status(), e.get_error_message()))
# 服務端異常,一般為參數錯誤或者流控錯誤。
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()))

詳細代碼請參見GetRange@GitHub

常見問題

相關文檔

  • 如果要使用索引技術加速資料查詢,您可以通過二級索引或者多元索引功能實現。更多資訊,請參見二級索引或者多元索引

  • 如果要可視化展示表中資料,您可以通過對接DataV或者Grafana工具實現。更多資訊,請參見資料視覺效果

  • 如果要下載表中資料到本地,您可以通過DataX、Table Store命令列CLI工具實現。更多資訊,請參見將Table Store資料下載到本地檔案

  • 如果要計算與分析表中資料,您可以通過Table StoreSQL查詢實現。更多資訊,請參見SQL查詢

    說明

    您還可以通過MaxCompute、Spark、Hive或者HadoopMR、Function Compute、Flink等計算引擎實現表中資料的計算與分析。具體操作,請參見計算與分析