1414
1515"""User-friendly container for Google Cloud Bigtable Row."""
1616
17- import struct
18-
1917from google .cloud ._helpers import (
2018 _datetime_from_microseconds , # type: ignore
2119 _microseconds_from_datetime , # type: ignore
2220 _to_bytes , # type: ignore
2321)
2422
25- from google .cloud .bigtable_v2 .types import data as data_v2_pb2
26-
27- _PACK_I64 = struct .Struct (">q" ).pack
23+ from google .cloud .bigtable .data import mutations
24+ from google .cloud .bigtable .data import read_modify_write_rules as rmw_rules
2825
2926MAX_MUTATIONS = 100000
3027"""The maximum number of mutations that a row can accumulate."""
@@ -158,26 +155,21 @@ def _set_cell(self, column_family_id, column, value, timestamp=None, state=None)
158155 :param state: (Optional) The state that is passed along to
159156 :meth:`_get_mutations`.
160157 """
161- column = _to_bytes (column )
162- if isinstance (value , int ):
163- value = _PACK_I64 (value )
164- value = _to_bytes (value )
165158 if timestamp is None :
166- # Use -1 for current Bigtable server time.
167- timestamp_micros = - 1
159+ # Use current Bigtable server time.
160+ timestamp_micros = mutations . _SERVER_SIDE_TIMESTAMP
168161 else :
169162 timestamp_micros = _microseconds_from_datetime (timestamp )
170163 # Truncate to millisecond granularity.
171164 timestamp_micros -= timestamp_micros % 1000
172165
173- mutation_val = data_v2_pb2 .Mutation .SetCell (
174- family_name = column_family_id ,
175- column_qualifier = column ,
166+ mutation = mutations .SetCell (
167+ family = column_family_id ,
168+ qualifier = column ,
169+ new_value = value ,
176170 timestamp_micros = timestamp_micros ,
177- value = value ,
178171 )
179- mutation_pb = data_v2_pb2 .Mutation (set_cell = mutation_val )
180- self ._get_mutations (state ).append (mutation_pb )
172+ self ._get_mutations (state ).append (mutation )
181173
182174 def _delete (self , state = None ):
183175 """Helper for :meth:`delete`
@@ -192,9 +184,7 @@ def _delete(self, state=None):
192184 :param state: (Optional) The state that is passed along to
193185 :meth:`_get_mutations`.
194186 """
195- mutation_val = data_v2_pb2 .Mutation .DeleteFromRow ()
196- mutation_pb = data_v2_pb2 .Mutation (delete_from_row = mutation_val )
197- self ._get_mutations (state ).append (mutation_pb )
187+ self ._get_mutations (state ).append (mutations .DeleteAllFromRow ())
198188
199189 def _delete_cells (self , column_family_id , columns , time_range = None , state = None ):
200190 """Helper for :meth:`delete_cell` and :meth:`delete_cells`.
@@ -221,33 +211,30 @@ def _delete_cells(self, column_family_id, columns, time_range=None, state=None):
221211 :param state: (Optional) The state that is passed along to
222212 :meth:`_get_mutations`.
223213 """
224- mutations_list = self ._get_mutations (state )
225214 if columns is self .ALL_COLUMNS :
226- mutation_val = data_v2_pb2 . Mutation . DeleteFromFamily (
227- family_name = column_family_id
215+ self . _get_mutations ( state ). append (
216+ mutations . DeleteAllFromFamily ( family_to_delete = column_family_id )
228217 )
229- mutation_pb = data_v2_pb2 .Mutation (delete_from_family = mutation_val )
230- mutations_list .append (mutation_pb )
231218 else :
232- delete_kwargs = {}
233- if time_range is not None :
234- delete_kwargs [ "time_range" ] = time_range . _to_pb ( )
219+ timestamps = time_range . _to_dict () if time_range else {}
220+ start_timestamp_micros = timestamps . get ( "start_timestamp_micros" )
221+ end_timestamp_micros = timestamps . get ( "end_timestamp_micros" )
235222
236223 to_append = []
237224 for column in columns :
238225 column = _to_bytes (column )
239- # time_range will never change if present, but the rest of
240- # delete_kwargs will
241- delete_kwargs .update (
242- family_name = column_family_id , column_qualifier = column
226+ to_append .append (
227+ mutations .DeleteRangeFromColumn (
228+ family = column_family_id ,
229+ qualifier = column ,
230+ start_timestamp_micros = start_timestamp_micros ,
231+ end_timestamp_micros = end_timestamp_micros ,
232+ )
243233 )
244- mutation_val = data_v2_pb2 .Mutation .DeleteFromColumn (** delete_kwargs )
245- mutation_pb = data_v2_pb2 .Mutation (delete_from_column = mutation_val )
246- to_append .append (mutation_pb )
247234
248235 # We don't add the mutations until all columns have been
249236 # processed without error.
250- mutations_list .extend (to_append )
237+ self . _get_mutations ( state ) .extend (to_append )
251238
252239
253240class DirectRow (_SetDeleteRow ):
@@ -285,7 +272,7 @@ class DirectRow(_SetDeleteRow):
285272
286273 def __init__ (self , row_key , table = None ):
287274 super (DirectRow , self ).__init__ (row_key , table )
288- self ._pb_mutations = []
275+ self ._mutations = []
289276
290277 def _get_mutations (self , state = None ): # pylint: disable=unused-argument
291278 """Gets the list of mutations for a given state.
@@ -300,7 +287,12 @@ def _get_mutations(self, state=None): # pylint: disable=unused-argument
300287 :rtype: list
301288 :returns: The list to add new mutations to (for the current state).
302289 """
303- return self ._pb_mutations
290+ return self ._mutations
291+
292+ def _get_mutation_pbs (self ):
293+ """Gets the list of mutation protos."""
294+
295+ return [mut ._to_pb () for mut in self ._get_mutations ()]
304296
305297 def get_mutations_size (self ):
306298 """Gets the total mutations size for current row
@@ -314,7 +306,7 @@ def get_mutations_size(self):
314306 """
315307
316308 mutation_size = 0
317- for mutation in self ._get_mutations ():
309+ for mutation in self ._get_mutation_pbs ():
318310 mutation_size += mutation ._pb .ByteSize ()
319311
320312 return mutation_size
@@ -487,7 +479,7 @@ def clear(self):
487479 :end-before: [END bigtable_api_row_clear]
488480 :dedent: 4
489481 """
490- del self ._pb_mutations [:]
482+ del self ._mutations [:]
491483
492484
493485class ConditionalRow (_SetDeleteRow ):
@@ -598,17 +590,15 @@ def commit(self):
598590 % (MAX_MUTATIONS , num_true_mutations , num_false_mutations )
599591 )
600592
601- data_client = self ._table ._instance ._client .table_data_client
602- resp = data_client .check_and_mutate_row (
603- table_name = self ._table .name ,
593+ table = self ._table ._table_impl
594+ resp = table .check_and_mutate_row (
604595 row_key = self ._row_key ,
605- predicate_filter = self ._filter ._to_pb (),
606- app_profile_id = self ._table ._app_profile_id ,
607- true_mutations = true_mutations ,
608- false_mutations = false_mutations ,
596+ predicate = self ._filter ,
597+ true_case_mutations = true_mutations ,
598+ false_case_mutations = false_mutations ,
609599 )
610600 self .clear ()
611- return resp . predicate_matched
601+ return resp
612602
613603 # pylint: disable=arguments-differ
614604 def set_cell (self , column_family_id , column , value , timestamp = None , state = True ):
@@ -798,7 +788,7 @@ class AppendRow(Row):
798788
799789 def __init__ (self , row_key , table ):
800790 super (AppendRow , self ).__init__ (row_key , table )
801- self ._rule_pb_list = []
791+ self ._rule_list = []
802792
803793 def clear (self ):
804794 """Removes all currently accumulated modifications on current row.
@@ -810,7 +800,7 @@ def clear(self):
810800 :end-before: [END bigtable_api_row_clear]
811801 :dedent: 4
812802 """
813- del self ._rule_pb_list [:]
803+ del self ._rule_list [:]
814804
815805 def append_cell_value (self , column_family_id , column , value ):
816806 """Appends a value to an existing cell.
@@ -843,12 +833,11 @@ def append_cell_value(self, column_family_id, column, value):
843833 the targeted cell is unset, it will be treated as
844834 containing the empty string.
845835 """
846- column = _to_bytes ( column )
847- value = _to_bytes ( value )
848- rule_pb = data_v2_pb2 . ReadModifyWriteRule (
849- family_name = column_family_id , column_qualifier = column , append_value = value
836+ self . _rule_list . append (
837+ rmw_rules . AppendValueRule (
838+ family = column_family_id , qualifier = column , append_value = value
839+ )
850840 )
851- self ._rule_pb_list .append (rule_pb )
852841
853842 def increment_cell_value (self , column_family_id , column , int_value ):
854843 """Increments a value in an existing cell.
@@ -887,13 +876,11 @@ def increment_cell_value(self, column_family_id, column, int_value):
887876 big-endian signed integer), or the entire request
888877 will fail.
889878 """
890- column = _to_bytes (column )
891- rule_pb = data_v2_pb2 .ReadModifyWriteRule (
892- family_name = column_family_id ,
893- column_qualifier = column ,
894- increment_amount = int_value ,
879+ self ._rule_list .append (
880+ rmw_rules .IncrementRule (
881+ family = column_family_id , qualifier = column , increment_amount = int_value
882+ )
895883 )
896- self ._rule_pb_list .append (rule_pb )
897884
898885 def commit (self ):
899886 """Makes a ``ReadModifyWriteRow`` API request.
@@ -926,7 +913,7 @@ def commit(self):
926913 :raises: :class:`ValueError <exceptions.ValueError>` if the number of
927914 mutations exceeds the :data:`MAX_MUTATIONS`.
928915 """
929- num_mutations = len (self ._rule_pb_list )
916+ num_mutations = len (self ._rule_list )
930917 if num_mutations == 0 :
931918 return {}
932919 if num_mutations > MAX_MUTATIONS :
@@ -935,12 +922,10 @@ def commit(self):
935922 "allowable %d." % (num_mutations , MAX_MUTATIONS )
936923 )
937924
938- data_client = self ._table ._instance ._client .table_data_client
939- row_response = data_client .read_modify_write_row (
940- table_name = self ._table .name ,
925+ table = self ._table ._table_impl
926+ row_response = table .read_modify_write_row (
941927 row_key = self ._row_key ,
942- rules = self ._rule_pb_list ,
943- app_profile_id = self ._table ._app_profile_id ,
928+ rules = self ._rule_list ,
944929 )
945930
946931 # Reset modifications after commit-ing request.
@@ -984,47 +969,13 @@ def _parse_rmw_row_response(row_response):
984969 }
985970 """
986971 result = {}
987- for column_family in row_response .row .families :
988- column_family_id , curr_family = _parse_family_pb (column_family )
989- result [column_family_id ] = curr_family
972+ for cell in row_response .cells :
973+ column_family = result .setdefault (cell .family , {})
974+ column = column_family .setdefault (cell .qualifier , [])
975+ column .append ((cell .value , _datetime_from_microseconds (cell .timestamp_micros )))
990976 return result
991977
992978
993- def _parse_family_pb (family_pb ):
994- """Parses a Family protobuf into a dictionary.
995-
996- :type family_pb: :class:`._generated.data_pb2.Family`
997- :param family_pb: A protobuf
998-
999- :rtype: tuple
1000- :returns: A string and dictionary. The string is the name of the
1001- column family and the dictionary has column names (within the
1002- family) as keys and cell lists as values. Each cell is
1003- represented with a two-tuple with the value (in bytes) and the
1004- timestamp for the cell. For example:
1005-
1006- .. code:: python
1007-
1008- {
1009- b'col-name1': [
1010- (b'cell-val', datetime.datetime(...)),
1011- (b'cell-val-newer', datetime.datetime(...)),
1012- ],
1013- b'col-name2': [
1014- (b'altcol-cell-val', datetime.datetime(...)),
1015- ],
1016- }
1017- """
1018- result = {}
1019- for column in family_pb .columns :
1020- result [column .qualifier ] = cells = []
1021- for cell in column .cells :
1022- val_pair = (cell .value , _datetime_from_microseconds (cell .timestamp_micros ))
1023- cells .append (val_pair )
1024-
1025- return family_pb .name , result
1026-
1027-
1028979class PartialRowData (object ):
1029980 """Representation of partial row in a Google Cloud Bigtable Table.
1030981
0 commit comments