1414
1515"""User-friendly container for Google Cloud Bigtable Row."""
1616
17-
18- import struct
19-
2017from google .cloud ._helpers import _datetime_from_microseconds # type: ignore
2118from google .cloud ._helpers import _microseconds_from_datetime # type: ignore
2219from google .cloud ._helpers import _to_bytes # type: ignore
23- from google .cloud .bigtable_v2 .types import data as data_v2_pb2
2420
21+ from google .cloud .bigtable .data import mutations
22+ from google .cloud .bigtable .data import read_modify_write_rules as rmw_rules
2523
26- _PACK_I64 = struct .Struct (">q" ).pack
2724
2825MAX_MUTATIONS = 100000
2926"""The maximum number of mutations that a row can accumulate."""
@@ -157,26 +154,21 @@ def _set_cell(self, column_family_id, column, value, timestamp=None, state=None)
157154 :param state: (Optional) The state that is passed along to
158155 :meth:`_get_mutations`.
159156 """
160- column = _to_bytes (column )
161- if isinstance (value , int ):
162- value = _PACK_I64 (value )
163- value = _to_bytes (value )
164157 if timestamp is None :
165- # Use -1 for current Bigtable server time.
166- timestamp_micros = - 1
158+ # Use current Bigtable server time.
159+ timestamp_micros = mutations . _SERVER_SIDE_TIMESTAMP
167160 else :
168161 timestamp_micros = _microseconds_from_datetime (timestamp )
169162 # Truncate to millisecond granularity.
170163 timestamp_micros -= timestamp_micros % 1000
171164
172- mutation_val = data_v2_pb2 .Mutation .SetCell (
173- family_name = column_family_id ,
174- column_qualifier = column ,
165+ mutation = mutations .SetCell (
166+ family = column_family_id ,
167+ qualifier = column ,
168+ new_value = value ,
175169 timestamp_micros = timestamp_micros ,
176- value = value ,
177170 )
178- mutation_pb = data_v2_pb2 .Mutation (set_cell = mutation_val )
179- self ._get_mutations (state ).append (mutation_pb )
171+ self ._get_mutations (state ).append (mutation )
180172
181173 def _delete (self , state = None ):
182174 """Helper for :meth:`delete`
@@ -191,9 +183,7 @@ def _delete(self, state=None):
191183 :param state: (Optional) The state that is passed along to
192184 :meth:`_get_mutations`.
193185 """
194- mutation_val = data_v2_pb2 .Mutation .DeleteFromRow ()
195- mutation_pb = data_v2_pb2 .Mutation (delete_from_row = mutation_val )
196- self ._get_mutations (state ).append (mutation_pb )
186+ self ._get_mutations (state ).append (mutations .DeleteAllFromRow ())
197187
198188 def _delete_cells (self , column_family_id , columns , time_range = None , state = None ):
199189 """Helper for :meth:`delete_cell` and :meth:`delete_cells`.
@@ -222,27 +212,28 @@ def _delete_cells(self, column_family_id, columns, time_range=None, state=None):
222212 """
223213 mutations_list = self ._get_mutations (state )
224214 if columns is self .ALL_COLUMNS :
225- mutation_val = data_v2_pb2 . Mutation . DeleteFromFamily (
226- family_name = column_family_id
215+ self . _get_mutations ( state ). append (
216+ mutations . DeleteAllFromFamily ( family_to_delete = column_family_id )
227217 )
228- mutation_pb = data_v2_pb2 .Mutation (delete_from_family = mutation_val )
229- mutations_list .append (mutation_pb )
230218 else :
231- delete_kwargs = {}
219+ start_timestamp_micros = None
220+ end_timestamp_micros = None
232221 if time_range is not None :
233- delete_kwargs ["time_range" ] = time_range ._to_pb ()
222+ timestamps = time_range ._to_dict ()
223+ start_timestamp_micros = timestamps .get ("start_timestamp_micros" )
224+ end_timestamp_micros = timestamps .get ("end_timestamp_micros" )
234225
235226 to_append = []
236227 for column in columns :
237228 column = _to_bytes (column )
238- # time_range will never change if present, but the rest of
239- # delete_kwargs will
240- delete_kwargs .update (
241- family_name = column_family_id , column_qualifier = column
229+ to_append .append (
230+ mutations .DeleteRangeFromColumn (
231+ family = column_family_id ,
232+ qualifier = column ,
233+ start_timestamp_micros = start_timestamp_micros ,
234+ end_timestamp_micros = end_timestamp_micros ,
235+ )
242236 )
243- mutation_val = data_v2_pb2 .Mutation .DeleteFromColumn (** delete_kwargs )
244- mutation_pb = data_v2_pb2 .Mutation (delete_from_column = mutation_val )
245- to_append .append (mutation_pb )
246237
247238 # We don't add the mutations until all columns have been
248239 # processed without error.
@@ -284,7 +275,7 @@ class DirectRow(_SetDeleteRow):
284275
285276 def __init__ (self , row_key , table = None ):
286277 super (DirectRow , self ).__init__ (row_key , table )
287- self ._pb_mutations = []
278+ self ._mutations = []
288279
289280 def _get_mutations (self , state = None ): # pylint: disable=unused-argument
290281 """Gets the list of mutations for a given state.
@@ -299,7 +290,12 @@ def _get_mutations(self, state=None): # pylint: disable=unused-argument
299290 :rtype: list
300291 :returns: The list to add new mutations to (for the current state).
301292 """
302- return self ._pb_mutations
293+ return self ._mutations
294+
295+ def _get_mutation_pbs (self ):
296+ """Gets the list of mutation protos."""
297+
298+ return [mut ._to_pb () for mut in self ._get_mutations ()]
303299
304300 def get_mutations_size (self ):
305301 """Gets the total mutations size for current row
@@ -313,7 +309,7 @@ def get_mutations_size(self):
313309 """
314310
315311 mutation_size = 0
316- for mutation in self ._get_mutations ():
312+ for mutation in self ._get_mutation_pbs ():
317313 mutation_size += mutation ._pb .ByteSize ()
318314
319315 return mutation_size
@@ -486,7 +482,7 @@ def clear(self):
486482 :end-before: [END bigtable_api_row_clear]
487483 :dedent: 4
488484 """
489- del self ._pb_mutations [:]
485+ del self ._mutations [:]
490486
491487
492488class ConditionalRow (_SetDeleteRow ):
@@ -597,17 +593,15 @@ def commit(self):
597593 % (MAX_MUTATIONS , num_true_mutations , num_false_mutations )
598594 )
599595
600- data_client = self ._table ._instance ._client .table_data_client
601- resp = data_client .check_and_mutate_row (
602- table_name = self ._table .name ,
596+ table = self ._table ._table_impl
597+ resp = table .check_and_mutate_row (
603598 row_key = self ._row_key ,
604- predicate_filter = self ._filter ._to_pb (),
605- app_profile_id = self ._table ._app_profile_id ,
606- true_mutations = true_mutations ,
607- false_mutations = false_mutations ,
599+ predicate = self ._filter ,
600+ true_case_mutations = true_mutations ,
601+ false_case_mutations = false_mutations ,
608602 )
609603 self .clear ()
610- return resp . predicate_matched
604+ return resp
611605
612606 # pylint: disable=arguments-differ
613607 def set_cell (self , column_family_id , column , value , timestamp = None , state = True ):
@@ -797,7 +791,7 @@ class AppendRow(Row):
797791
798792 def __init__ (self , row_key , table ):
799793 super (AppendRow , self ).__init__ (row_key , table )
800- self ._rule_pb_list = []
794+ self ._rule_list = []
801795
802796 def clear (self ):
803797 """Removes all currently accumulated modifications on current row.
@@ -809,7 +803,7 @@ def clear(self):
809803 :end-before: [END bigtable_api_row_clear]
810804 :dedent: 4
811805 """
812- del self ._rule_pb_list [:]
806+ del self ._rule_list [:]
813807
814808 def append_cell_value (self , column_family_id , column , value ):
815809 """Appends a value to an existing cell.
@@ -842,12 +836,11 @@ def append_cell_value(self, column_family_id, column, value):
842836 the targeted cell is unset, it will be treated as
843837 containing the empty string.
844838 """
845- column = _to_bytes ( column )
846- value = _to_bytes ( value )
847- rule_pb = data_v2_pb2 . ReadModifyWriteRule (
848- family_name = column_family_id , column_qualifier = column , append_value = value
839+ self . _rule_list . append (
840+ rmw_rules . AppendValueRule (
841+ family = column_family_id , qualifier = column , append_value = value
842+ )
849843 )
850- self ._rule_pb_list .append (rule_pb )
851844
852845 def increment_cell_value (self , column_family_id , column , int_value ):
853846 """Increments a value in an existing cell.
@@ -886,13 +879,11 @@ def increment_cell_value(self, column_family_id, column, int_value):
886879 big-endian signed integer), or the entire request
887880 will fail.
888881 """
889- column = _to_bytes (column )
890- rule_pb = data_v2_pb2 .ReadModifyWriteRule (
891- family_name = column_family_id ,
892- column_qualifier = column ,
893- increment_amount = int_value ,
882+ self ._rule_list .append (
883+ rmw_rules .IncrementRule (
884+ family = column_family_id , qualifier = column , increment_amount = int_value
885+ )
894886 )
895- self ._rule_pb_list .append (rule_pb )
896887
897888 def commit (self ):
898889 """Makes a ``ReadModifyWriteRow`` API request.
@@ -925,7 +916,7 @@ def commit(self):
925916 :raises: :class:`ValueError <exceptions.ValueError>` if the number of
926917 mutations exceeds the :data:`MAX_MUTATIONS`.
927918 """
928- num_mutations = len (self ._rule_pb_list )
919+ num_mutations = len (self ._rule_list )
929920 if num_mutations == 0 :
930921 return {}
931922 if num_mutations > MAX_MUTATIONS :
@@ -934,12 +925,10 @@ def commit(self):
934925 "allowable %d." % (num_mutations , MAX_MUTATIONS )
935926 )
936927
937- data_client = self ._table ._instance ._client .table_data_client
938- row_response = data_client .read_modify_write_row (
939- table_name = self ._table .name ,
928+ table = self ._table ._table_impl
929+ row_response = table .read_modify_write_row (
940930 row_key = self ._row_key ,
941- rules = self ._rule_pb_list ,
942- app_profile_id = self ._table ._app_profile_id ,
931+ rules = self ._rule_list ,
943932 )
944933
945934 # Reset modifications after commit-ing request.
@@ -983,47 +972,13 @@ def _parse_rmw_row_response(row_response):
983972 }
984973 """
985974 result = {}
986- for column_family in row_response .row .families :
987- column_family_id , curr_family = _parse_family_pb (column_family )
988- result [column_family_id ] = curr_family
975+ for cell in row_response .cells :
976+ result .setdefault (cell .family , {}).setdefault (cell .qualifier , []).append (
977+ (cell .value , _datetime_from_microseconds (cell .timestamp_micros ))
978+ )
989979 return result
990980
991981
992- def _parse_family_pb (family_pb ):
993- """Parses a Family protobuf into a dictionary.
994-
995- :type family_pb: :class:`._generated.data_pb2.Family`
996- :param family_pb: A protobuf
997-
998- :rtype: tuple
999- :returns: A string and dictionary. The string is the name of the
1000- column family and the dictionary has column names (within the
1001- family) as keys and cell lists as values. Each cell is
1002- represented with a two-tuple with the value (in bytes) and the
1003- timestamp for the cell. For example:
1004-
1005- .. code:: python
1006-
1007- {
1008- b'col-name1': [
1009- (b'cell-val', datetime.datetime(...)),
1010- (b'cell-val-newer', datetime.datetime(...)),
1011- ],
1012- b'col-name2': [
1013- (b'altcol-cell-val', datetime.datetime(...)),
1014- ],
1015- }
1016- """
1017- result = {}
1018- for column in family_pb .columns :
1019- result [column .qualifier ] = cells = []
1020- for cell in column .cells :
1021- val_pair = (cell .value , _datetime_from_microseconds (cell .timestamp_micros ))
1022- cells .append (val_pair )
1023-
1024- return family_pb .name , result
1025-
1026-
1027982class PartialRowData (object ):
1028983 """Representation of partial row in a Google Cloud Bigtable Table.
1029984
0 commit comments