From ac6f9ae1e152140dfa69f95f00d1764e2fcf06be Mon Sep 17 00:00:00 2001 From: Danny Hermes Date: Fri, 15 Jan 2016 09:10:07 -0800 Subject: [PATCH] Adding Bigtable Row.increment_cell_value. Similar to #1388. The API accepts integers and then encodes them as bytes when stored in the table. --- gcloud/bigtable/row.py | 30 ++++++++++++++++++++++++++++++ gcloud/bigtable/test_row.py | 17 +++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/gcloud/bigtable/row.py b/gcloud/bigtable/row.py index ef4b7ef6fa6c0..eef6abca1a97c 100644 --- a/gcloud/bigtable/row.py +++ b/gcloud/bigtable/row.py @@ -75,6 +75,36 @@ def append_cell_value(self, column_family_id, column, value): append_value=value) self._rule_pb_list.append(rule_pb) + def increment_cell_value(self, column_family_id, column, int_value): + """Increments a value in an existing cell. + Assumes the value in the cell is stored as a 64 bit integer + serialized to bytes. + .. note:: + This method adds a read-modify rule protobuf to the accumulated + read-modify rules on this :class:`Row`, but does not make an API + request. To actually send an API request (with the rules) to the + Google Cloud Bigtable API, call :meth:`commit_modifications`. + :type column_family_id: str + :param column_family_id: The column family that contains the column. + Must be of the form + ``[_a-zA-Z0-9][-_.a-zA-Z0-9]*``. + :type column: bytes + :param column: The column within the column family where the cell + is located. + :type int_value: int + :param int_value: The value to increment the existing value in the cell + by. If the targeted cell is unset, it will be treated + as containing a zero. Otherwise, the targeted cell + must contain an 8-byte value (interpreted as a 64-bit + big-endian signed integer), or the entire request + will fail. + """ + column = _to_bytes(column) + rule_pb = data_pb2.ReadModifyWriteRule(family_name=column_family_id, + column_qualifier=column, + increment_amount=int_value) + self._rule_pb_list.append(rule_pb) + class RowFilter(object): """Basic filter to apply to cells in a row. diff --git a/gcloud/bigtable/test_row.py b/gcloud/bigtable/test_row.py index ea41c5d6ccc5f..c8a8cc1f77e6a 100644 --- a/gcloud/bigtable/test_row.py +++ b/gcloud/bigtable/test_row.py @@ -66,6 +66,23 @@ def test_append_cell_value(self): append_value=value) self.assertEqual(row._rule_pb_list, [expected_pb]) + def test_increment_cell_value(self): + from gcloud.bigtable._generated import bigtable_data_pb2 as data_pb2 + + table = object() + row_key = b'row_key' + row = self._makeOne(row_key, table) + self.assertEqual(row._rule_pb_list, []) + + column = b'column' + column_family_id = u'column_family_id' + int_value = 281330 + row.increment_cell_value(column_family_id, column, int_value) + expected_pb = data_pb2.ReadModifyWriteRule( + family_name=column_family_id, column_qualifier=column, + increment_amount=int_value) + self.assertEqual(row._rule_pb_list, [expected_pb]) + class Test_BoolFilter(unittest2.TestCase):