Tablestore では、単一行または複数行のデータを同時に書き込むことで、データテーブルにデータを書き込むことができます。ビジネス要件に基づいて、行を個別に書き込むことも、複数行のデータを同時に書き込むこともできます。このトピックでは、Java 用 Tablestore SDK を使用して Tablestore にデータを書き込む方法について説明します。
操作
Tablestore は、PutRow、UpdateRow、および BatchWriteRow 操作を提供しており、これらを使用してデータを書き込むことができます。ビジネス要件に基づいて、データ書き込み操作を選択してください。
操作 | 説明 | シナリオ |
PutRow 操作を呼び出して、単一行のデータを挿入できます。行が存在する場合、Tablestore は既存の行のすべての列からすべてのバージョンのデータを削除し、新しいデータを書き込みます。 | この操作は、少量のデータを書き込むシナリオに適しています。 | |
UpdateRow 操作を呼び出して、単一行のデータを更新できます。行に属性列を追加したり、行から属性列を削除したり、属性列から特定のバージョンのデータを削除したり、属性列の値を更新したりできます。行が存在しない場合は、新しい行が挿入されます。 | この操作は、既存のデータを更新するシナリオに適しています。たとえば、属性列を削除したり、特定のバージョンのデータを削除したり、属性列の値を更新したりする場合です。 | |
BatchWriteRow 操作を呼び出して、1 つ以上のテーブルに複数行のデータを同時に書き込むことができます。 BatchWriteRow 操作は、複数の PutRow、UpdateRow、および DeleteRow 操作で構成されます。BatchWriteRow 操作を呼び出す場合、サブ操作を構築するプロセスは、PutRow、UpdateRow、または DeleteRow 操作を呼び出すプロセスと同じです。 | この操作は、大量のデータを書き込み、削除、または更新するシナリオや、データを同時に書き込み、削除、および更新するシナリオに適しています。 |
前提条件
OTSClient インスタンスが初期化されていること。詳細については、OTSClient インスタンスの初期化を参照してください。
データテーブルが作成され、データがデータテーブルに書き込まれていること。
単一行のデータの挿入
API 操作
"""
説明: この操作は単一行のデータを書き込みます。操作で消費される容量ユニット (CU) の数が返されます。
table_name: テーブルの名前。
row: データテーブルに書き込む行。プライマリキー列と属性列が含まれます。
condition: 操作を実行するために満たす必要がある条件。条件を指定すると、Tablestore は操作を実行する前に、指定された条件が満たされているかどうかを確認します。条件が満たされている場合にのみ、操作が実行されます。 condition パラメータは、tablestore.metadata.Condition クラスのインスタンスです。
行存在条件と列値に基づく条件がサポートされています。行存在条件を指定する場合、ビジネス要件に基づいて、condition パラメータを IGNORE、EXPECT_EXIST、または EXPECT_NOT_EXIST に設定できます。
return_type: 返すデータのタイプ。 return_type パラメータは、tablestore.metadata.ReturnType クラスのインスタンスです。プライマリキーのみを返すことができます。ほとんどの場合、このパラメータは自動インクリメントプライマリキー列機能で使用されます。
レスポンス: 操作で消費される CU の数と返される行データ。
consumed: 操作で消費される CU の数。 consumed パラメータは、tablestore.metadata.CapacityUnit クラスのインスタンスです。
return_row: 返される行データ。プライマリキー列と属性列が含まれる場合があります。
例:
primary_key = [('gid',1), ('uid',101)]
attribute_columns = [('name','Mary'), ('mobile',111111111), ('address','City A in China'), ('age',20)]
row = Row(primary_key, attribute_columns)
condition = Condition('EXPECT_NOT_EXIST')
consumed, return_row = client.put_row('myTable', row, condition)
"""
def put_row(self, table_name, row, condition = None, return_type = None, transaction_id = None):
パラメータ
パラメータ | 説明 |
table_name | データテーブルの名前。 |
row | データの行。このパラメータには、次の設定項目が含まれます。
|
condition | 操作を実行するために満たす必要がある条件。行存在条件または列値に基づく条件を指定できます。詳細については、条件付き更新の設定を参照してください。 説明
|
return_type | 返すデータのタイプ。 return_type パラメータは、tablestore.metadata.ReturnType クラスのインスタンスです。プライマリキーのみを返すことができます。ほとんどの場合、このパラメータは自動インクリメントプライマリキー列機能で使用されます。 |
transaction_id | ローカルトランザクションの ID。ローカルトランザクション機能を使用してデータを削除する場合、このパラメータを設定する必要があります。 |
例
次のサンプルコードは、データの行を挿入する方法の例を示しています。
次の例では、age 属性列のデータバージョンは 1498184687000 で、これは 2017 年 6 月 23 日を示しています。現在の時刻と max_time_deviation パラメータの値の差が 1498184687000 より大きい場合、PutRow 操作は禁止されます。 max_time_deviation パラメータの値は、テーブルの作成時に指定されます。
# データテーブルの名前を指定します。
table_name = '<TABLE_NAME>'
# 最初のプライマリキー列は gid で、値は整数 1 です。2 番目のプライマリキー列は uid で、値は整数 101 です。
primary_key = [('gid',1), ('uid',101)]
# 行には 5 つの属性列が含まれています。
# 最初の属性列は name で、値は文字列 John です。最初の属性列のデータバージョン番号は指定されていません。システムは現在の時刻をデータバージョン番号として使用します。
# 2 番目の属性列は mobile で、値は整数 1390000**** です。2 番目の属性列のデータバージョン番号は指定されていません。システムは現在の時刻をデータバージョン番号として使用します。
# 3 番目の属性列は address で、値はバイナリ値 China です。3 番目の属性列のデータバージョン番号は指定されていません。システムは現在の時刻をデータバージョン番号として使用します。
# 4 番目の属性列は female で、値はブール値 False です。4 番目の属性列のデータバージョン番号は指定されていません。システムは現在の時刻をデータバージョン番号として使用します。
# 5 番目の属性列は age で、値は 29.7 です。1498184687000 が 5 番目の属性列のデータバージョン番号として指定されています。
attribute_columns = [('name','John'), ('mobile',1390000****),('address', bytearray('China', encoding='utf8')),('female', False), ('age', 29.7, 1498184687000)]
# primary_key と attribute_columns を使用して行を構築します。
row = Row(primary_key, attribute_columns)
# 指定された行が存在しないことを想定する行存在条件を指定します。指定された行が存在する場合、Condition Update Failed エラーが発生します。
condition = Condition(RowExistenceExpectation.EXPECT_NOT_EXIST)
try:
# put_row メソッドを呼び出すときに ReturnType パラメータを指定しない場合、return_row パラメータの値は None です。
consumed, return_row = client.put_row(table_name, row, condition)
# リクエストで消費される書き込み CU の数を表示します。
print('put row succeed, consume %s write cu.' % consumed.write)
# ほとんどの場合、クライアント例外はパラメータエラーまたはネットワーク例外が原因で発生します。
except OTSClientError as e:
print("put row failed, http_status:%d, error_message:%s" % (e.get_http_status(), e.get_error_message()))
# ほとんどの場合、サーバー例外はパラメータエラーまたはスロットリングエラーが原因で発生します。
except OTSServiceError as e:
print("put 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()))
詳細なサンプルコードを表示するには、PutRow@GitHub にアクセスしてください。
単一行のデータの更新
API 操作
"""
説明: この操作は単一行のデータを更新します。
table_name: テーブルの名前。
row: 更新する行。プライマリキー列と属性列が含まれます。プライマリキー列はリスト構造で、属性列は辞書構造です。
condition: 操作を実行するために満たす必要がある条件。条件を指定すると、Tablestore は操作を実行する前に、指定された条件が満たされているかどうかを確認します。条件が満たされている場合にのみ、操作が実行されます。 condition パラメータは、tablestore.metadata.Condition クラスのインスタンスです。
行存在条件と列値に基づく条件がサポートされています。行存在条件を指定する場合、ビジネス要件に基づいて、condition パラメータを IGNORE、EXPECT_EXIST、または EXPECT_NOT_EXIST に設定できます。
return_type: 返すデータのタイプ。 return_type パラメータは、tablestore.metadata.ReturnType クラスのインスタンスです。プライマリキーのみを返すことができます。ほとんどの場合、このパラメータは自動インクリメントプライマリキー列機能で使用されます。
レスポンス: 操作で消費される CU の数と return_row で指定された行データ。
consumed: 操作で消費される CU の数。 consumed パラメータは、tablestore.metadata.CapacityUnit クラスのインスタンスです。
return_row: 返される行データ。
例:
primary_key = [('gid',1), ('uid',101)]
update_of_attribute_columns = {
'put' : [('name','Jack'), ('address','City A in China')],
'delete' : [('mobile', 1493725896147)],
'delete_all' : [('age')],
'increment' : [('counter', 1)]
}
row = Row(primary_key, update_of_attribute_columns)
condition = Condition('EXPECT_EXIST')
consumed = client.update_row('myTable', row, condition)
"""
def update_row(self, table_name, row, condition, return_type = None, transaction_id = None):
パラメータ
パラメータ | 説明 |
table_name | データテーブルの名前。 |
row | データの行。このパラメータには、次の設定項目が含まれます。
|
condition | 操作を実行するために満たす必要がある条件。行存在条件または列値に基づく条件を指定できます。詳細については、条件付き更新の設定を参照してください。 |
return_type | 返すデータのタイプ。 return_type パラメータは、tablestore.metadata.ReturnType クラスのインスタンスです。プライマリキーのみを返すことができます。ほとんどの場合、このパラメータは自動インクリメントプライマリキー列機能で使用されます。 |
transaction_id | ローカルトランザクションの ID。ローカルトランザクション機能を使用してデータを削除する場合、このパラメータを設定する必要があります。 |
例
次のサンプルコードは、データの行を更新する方法の例を示しています。
# データテーブルの名前を指定します。
table_name = '<TABLE_NAME>'
# 最初のプライマリキー列は gid で、値は整数 1 です。2 番目のプライマリキー列は uid で、値は整数 101 です。
primary_key = [('gid',1), ('uid',101)]
# 更新タイプには、PUT、DELETE、および DELETE_ALL が含まれます。
# PUT: 属性列を追加するか、属性列の既存の値を更新します。この例では、2 つの属性列が追加されます。最初の列は name で、値は David です。2 番目の列は address で、値は Hongkong です。
# DELETE: 特定のバージョン (タイムスタンプ) のデータを削除します。この例では、address 列でデータバージョン番号が 1488436949003 のデータが削除されます。
# DELETE_ALL: 列を削除します。この例では、mobile 列と age 列のすべてのバージョンのデータが削除されます。
update_of_attribute_columns = {
'PUT' : [('name','David'), ('address','Hongkong')],
'DELETE' : [('address', None, 1488436949003)],
'DELETE_ALL' : [('mobile'), ('age')],
}
row = Row(primary_key, update_of_attribute_columns)
# この例では、Condition パラメータは RowExistenceExpectation.IGNORE に設定されています。これは、行が存在するかどうかに関係なく行が更新されることを指定します。
condition = Condition(RowExistenceExpectation.IGNORE, SingleColumnCondition("age", 20, ComparatorType.EQUAL)) # この行が存在する場合にのみ行を更新します
try:
consumed, return_row = client.update_row(table_name, row, condition)
# リクエストで消費される書き込み CU の数を表示します。
print('put row succeed, consume %s write cu.' % consumed.write)
# ほとんどの場合、クライアント例外はパラメータエラーまたはネットワーク例外が原因で発生します。
except OTSClientError as e:
print("update row failed, http_status:%d, error_message:%s" % (e.get_http_status(), e.get_error_message()))
# ほとんどの場合、サーバー例外はパラメータエラーまたはスロットリングエラーが原因で発生します。
except OTSServiceError as e:
print("update 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()))
詳細なサンプルコードを表示するには、UpdateRow@GitHub にアクセスしてください。
複数行のデータの同時書き込み
使用上の注意
BatchWriteRow 操作を呼び出して複数行のデータを同時に書き込むと、一部の行の書き込みに失敗することがあります。この場合、Tablestore は例外を返しません。 Tablestore は、失敗した行のインデックスとエラーメッセージが含まれる BatchWriteRowResponse を返します。BatchWriteRow 操作を呼び出すときは、戻り値を確認してすべての行が書き込まれたかどうかを判断してください。戻り値を確認しないと、書き込みに失敗した行が無視される可能性があります。
API 操作
"""
説明: この操作は複数行のデータを同時に書き込みます。
request = MiltiTableInBatchWriteRowItem()
request.add(TableInBatchWriteRowItem(table0, row_items))
request.add(TableInBatchWriteRowItem(table1, row_items))
response = client.batch_write_row(request)
response: 返された結果。 response パラメータのタイプは tablestore.metadata.BatchWriteRowResponse です。
"""
def batch_write_row(self, request):
例
次のサンプルコードは、複数行のデータを同時に書き込む方法の例を示しています。
put_row_items = []
# PutRow 操作を呼び出して行を挿入します。
for i in range(0, 20):
primary_key = [('gid',i), ('uid',i+1)]
attribute_columns = [('name','somebody'+str(i)), ('address','somewhere'+str(i)), ('age',i)]
row = Row(primary_key, attribute_columns)
condition = Condition(RowExistenceExpectation.IGNORE)
item = PutRowItem(row, condition)
put_row_items.append(item)
# UpdateRow 操作を呼び出して行を更新します。
for i in range(0, 10):
primary_key = [('gid',i), ('uid',i+1)]
attribute_columns = {'put': [('name','somebody'+str(i)), ('address','somewhere'+str(i)), ('age',i)]}
row = Row(primary_key, attribute_columns)
condition = Condition(RowExistenceExpectation.IGNORE, SingleColumnCondition("age", i, ComparatorType.EQUAL))
item = UpdateRowItem(row, condition)
put_row_items.append(item)
# DeleteRow 操作を呼び出して行を削除します。
delete_row_items = []
for i in range(10, 20):
primary_key = [('gid',i), ('uid',i+1)]
row = Row(primary_key)
condition = Condition(RowExistenceExpectation.IGNORE)
item = DeleteRowItem(row, condition)
delete_row_items.append(item)
# 複数行のデータを同時に書き込むリクエストを構築します。
request = BatchWriteRowRequest()
request.add(TableInBatchWriteRowItem('<TABLE_NAME>', put_row_items))
request.add(TableInBatchWriteRowItem('<DELETE_TABLE_NAME>', delete_row_items))
# batch_write_row メソッドを呼び出して複数行のデータを同時に書き込むと、リクエストパラメータエラーなどのエラーが発生した場合に例外が発生することがあります。一部の行の操作が失敗した場合、例外が発生しない場合がありますが、内部項目は失敗する可能性があります。
try:
result = client.batch_write_row(request)
print('Result status: %s'%(result.is_all_succeed()))
# PutRow 操作の結果を確認します。
print('check first table\'s put results:')
succ, fail = result.get_put()
for item in succ:
print('Put succeed, consume %s write cu.' % item.consumed.write)
for item in fail:
print('Put failed, error code: %s, error message: %s' % (item.error_code, item.error_message))
# UpdateRow 操作の結果を確認します。
print('check first table\'s update results:')
succ, fail = result.get_update()
for item in succ:
print('Update succeed, consume %s write cu.' % item.consumed.write)
for item in fail:
print('Update failed, error code: %s, error message: %s' % (item.error_code, item.error_message))
# DeleteRow 操作の結果を確認します。
print('check second table\'s delete results:')
succ, fail = result.get_delete()
for item in succ:
print('Delete succeed, consume %s write cu.' % item.consumed.write)
for item in fail:
print('Delete 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()))
詳細なサンプルコードを表示するには、BatchWriteRow@GitHub にアクセスしてください。
FAQ
参考資料
指定された条件に基づいて高並列アプリケーションのデータを更新するには、条件付き更新機能を使用できます。詳細については、条件付き更新の構成を参照してください。
さまざまなトピックのページビュー (PV) 数など、オンラインアプリケーションに関するリアルタイム統計を収集するには、アトミックカウンタ機能を使用できます。詳細については、アトミックカウンタ機能の使用を参照してください。
1 つ以上のデータ行を書き込むためのアトミック操作を実行するには、ローカルトランザクション機能を使用できます。詳細については、ローカルトランザクション機能の使用を参照してください。
テーブルにデータを書き込んだ後、ビジネス要件に基づいてテーブル内のデータを読み取ったり削除したりできます。詳細については、データの読み取りとデータの削除を参照してください。