google-cloud-bigtable 2.30.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- google/cloud/bigtable/__init__.py +25 -0
- google/cloud/bigtable/app_profile.py +377 -0
- google/cloud/bigtable/backup.py +490 -0
- google/cloud/bigtable/batcher.py +414 -0
- google/cloud/bigtable/client.py +475 -0
- google/cloud/bigtable/cluster.py +541 -0
- google/cloud/bigtable/column_family.py +362 -0
- google/cloud/bigtable/data/__init__.py +103 -0
- google/cloud/bigtable/data/_async/__init__.py +25 -0
- google/cloud/bigtable/data/_async/_mutate_rows.py +226 -0
- google/cloud/bigtable/data/_async/_read_rows.py +363 -0
- google/cloud/bigtable/data/_async/client.py +1522 -0
- google/cloud/bigtable/data/_async/mutations_batcher.py +534 -0
- google/cloud/bigtable/data/_cross_sync/__init__.py +20 -0
- google/cloud/bigtable/data/_cross_sync/_decorators.py +441 -0
- google/cloud/bigtable/data/_cross_sync/_mapping_meta.py +64 -0
- google/cloud/bigtable/data/_cross_sync/cross_sync.py +334 -0
- google/cloud/bigtable/data/_helpers.py +249 -0
- google/cloud/bigtable/data/_sync_autogen/_mutate_rows.py +182 -0
- google/cloud/bigtable/data/_sync_autogen/_read_rows.py +304 -0
- google/cloud/bigtable/data/_sync_autogen/client.py +1293 -0
- google/cloud/bigtable/data/_sync_autogen/mutations_batcher.py +449 -0
- google/cloud/bigtable/data/exceptions.py +340 -0
- google/cloud/bigtable/data/execute_query/__init__.py +43 -0
- google/cloud/bigtable/data/execute_query/_async/__init__.py +13 -0
- google/cloud/bigtable/data/execute_query/_async/execute_query_iterator.py +291 -0
- google/cloud/bigtable/data/execute_query/_byte_cursor.py +123 -0
- google/cloud/bigtable/data/execute_query/_checksum.py +43 -0
- google/cloud/bigtable/data/execute_query/_parameters_formatting.py +155 -0
- google/cloud/bigtable/data/execute_query/_query_result_parsing_utils.py +134 -0
- google/cloud/bigtable/data/execute_query/_reader.py +122 -0
- google/cloud/bigtable/data/execute_query/_sync_autogen/execute_query_iterator.py +239 -0
- google/cloud/bigtable/data/execute_query/metadata.py +399 -0
- google/cloud/bigtable/data/execute_query/values.py +123 -0
- google/cloud/bigtable/data/mutations.py +380 -0
- google/cloud/bigtable/data/read_modify_write_rules.py +112 -0
- google/cloud/bigtable/data/read_rows_query.py +536 -0
- google/cloud/bigtable/data/row.py +535 -0
- google/cloud/bigtable/data/row_filters.py +968 -0
- google/cloud/bigtable/encryption_info.py +64 -0
- google/cloud/bigtable/enums.py +223 -0
- google/cloud/bigtable/error.py +64 -0
- google/cloud/bigtable/gapic_version.py +16 -0
- google/cloud/bigtable/helpers.py +31 -0
- google/cloud/bigtable/instance.py +789 -0
- google/cloud/bigtable/policy.py +255 -0
- google/cloud/bigtable/row.py +1267 -0
- google/cloud/bigtable/row_data.py +380 -0
- google/cloud/bigtable/row_filters.py +838 -0
- google/cloud/bigtable/row_merger.py +250 -0
- google/cloud/bigtable/row_set.py +213 -0
- google/cloud/bigtable/table.py +1409 -0
- google/cloud/bigtable_admin/__init__.py +410 -0
- google/cloud/bigtable_admin/gapic_version.py +16 -0
- google/cloud/bigtable_admin/py.typed +2 -0
- google/cloud/bigtable_admin_v2/__init__.py +250 -0
- google/cloud/bigtable_admin_v2/gapic_metadata.json +962 -0
- google/cloud/bigtable_admin_v2/gapic_version.py +16 -0
- google/cloud/bigtable_admin_v2/py.typed +2 -0
- google/cloud/bigtable_admin_v2/services/__init__.py +15 -0
- google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/__init__.py +22 -0
- google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/async_client.py +3465 -0
- google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/client.py +3944 -0
- google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/pagers.py +681 -0
- google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/transports/__init__.py +40 -0
- google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/transports/base.py +751 -0
- google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/transports/grpc.py +1249 -0
- google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/transports/grpc_asyncio.py +1579 -0
- google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/transports/rest.py +6820 -0
- google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/transports/rest_base.py +1746 -0
- google/cloud/bigtable_admin_v2/services/bigtable_table_admin/__init__.py +22 -0
- google/cloud/bigtable_admin_v2/services/bigtable_table_admin/async_client.py +3472 -0
- google/cloud/bigtable_admin_v2/services/bigtable_table_admin/client.py +3949 -0
- google/cloud/bigtable_admin_v2/services/bigtable_table_admin/pagers.py +669 -0
- google/cloud/bigtable_admin_v2/services/bigtable_table_admin/transports/__init__.py +40 -0
- google/cloud/bigtable_admin_v2/services/bigtable_table_admin/transports/base.py +708 -0
- google/cloud/bigtable_admin_v2/services/bigtable_table_admin/transports/grpc.py +1257 -0
- google/cloud/bigtable_admin_v2/services/bigtable_table_admin/transports/grpc_asyncio.py +1549 -0
- google/cloud/bigtable_admin_v2/services/bigtable_table_admin/transports/rest.py +6609 -0
- google/cloud/bigtable_admin_v2/services/bigtable_table_admin/transports/rest_base.py +1714 -0
- google/cloud/bigtable_admin_v2/types/__init__.py +248 -0
- google/cloud/bigtable_admin_v2/types/bigtable_instance_admin.py +1364 -0
- google/cloud/bigtable_admin_v2/types/bigtable_table_admin.py +1715 -0
- google/cloud/bigtable_admin_v2/types/common.py +81 -0
- google/cloud/bigtable_admin_v2/types/instance.py +819 -0
- google/cloud/bigtable_admin_v2/types/table.py +1028 -0
- google/cloud/bigtable_admin_v2/types/types.py +776 -0
- google/cloud/bigtable_v2/__init__.py +136 -0
- google/cloud/bigtable_v2/gapic_metadata.json +193 -0
- google/cloud/bigtable_v2/gapic_version.py +16 -0
- google/cloud/bigtable_v2/py.typed +2 -0
- google/cloud/bigtable_v2/services/__init__.py +15 -0
- google/cloud/bigtable_v2/services/bigtable/__init__.py +22 -0
- google/cloud/bigtable_v2/services/bigtable/async_client.py +1741 -0
- google/cloud/bigtable_v2/services/bigtable/client.py +2194 -0
- google/cloud/bigtable_v2/services/bigtable/transports/__init__.py +38 -0
- google/cloud/bigtable_v2/services/bigtable/transports/base.py +343 -0
- google/cloud/bigtable_v2/services/bigtable/transports/grpc.py +660 -0
- google/cloud/bigtable_v2/services/bigtable/transports/grpc_asyncio.py +762 -0
- google/cloud/bigtable_v2/services/bigtable/transports/rest.py +2489 -0
- google/cloud/bigtable_v2/services/bigtable/transports/rest_base.py +711 -0
- google/cloud/bigtable_v2/types/__init__.py +138 -0
- google/cloud/bigtable_v2/types/bigtable.py +1531 -0
- google/cloud/bigtable_v2/types/data.py +1612 -0
- google/cloud/bigtable_v2/types/feature_flags.py +119 -0
- google/cloud/bigtable_v2/types/request_stats.py +171 -0
- google/cloud/bigtable_v2/types/response_params.py +64 -0
- google/cloud/bigtable_v2/types/types.py +579 -0
- google_cloud_bigtable-2.30.0.data/scripts/fixup_bigtable_admin_v2_keywords.py +233 -0
- google_cloud_bigtable-2.30.0.data/scripts/fixup_bigtable_v2_keywords.py +186 -0
- google_cloud_bigtable-2.30.0.dist-info/LICENSE +202 -0
- google_cloud_bigtable-2.30.0.dist-info/METADATA +154 -0
- google_cloud_bigtable-2.30.0.dist-info/RECORD +115 -0
- google_cloud_bigtable-2.30.0.dist-info/WHEEL +5 -0
- google_cloud_bigtable-2.30.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,535 @@
|
|
|
1
|
+
# Copyright 2023 Google LLC
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
#
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
from collections import OrderedDict
|
|
18
|
+
from typing import Generator, overload, Any
|
|
19
|
+
from functools import total_ordering
|
|
20
|
+
|
|
21
|
+
from google.cloud.bigtable_v2.types import Row as RowPB
|
|
22
|
+
|
|
23
|
+
# Type aliases used internally for readability.
|
|
24
|
+
_family_type = str
|
|
25
|
+
_qualifier_type = bytes
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class Row:
|
|
29
|
+
"""
|
|
30
|
+
Model class for row data returned from server
|
|
31
|
+
|
|
32
|
+
Does not represent all data contained in the row, only data returned by a
|
|
33
|
+
query.
|
|
34
|
+
Expected to be read-only to users, and written by backend
|
|
35
|
+
|
|
36
|
+
Can be indexed by family and qualifier to get cells in the row::
|
|
37
|
+
|
|
38
|
+
cells = row["family", "qualifier"]
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
key: Row key
|
|
42
|
+
cells: List of cells in the row
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
__slots__ = ("row_key", "cells", "_index_data")
|
|
46
|
+
|
|
47
|
+
def __init__(
|
|
48
|
+
self,
|
|
49
|
+
key: bytes,
|
|
50
|
+
cells: list[Cell],
|
|
51
|
+
):
|
|
52
|
+
"""
|
|
53
|
+
Row objects are not intended to be created by users.
|
|
54
|
+
They are returned by the Bigtable backend.
|
|
55
|
+
"""
|
|
56
|
+
self.row_key = key
|
|
57
|
+
self.cells: list[Cell] = cells
|
|
58
|
+
# index is lazily created when needed
|
|
59
|
+
self._index_data: OrderedDict[
|
|
60
|
+
_family_type, OrderedDict[_qualifier_type, list[Cell]]
|
|
61
|
+
] | None = None
|
|
62
|
+
|
|
63
|
+
@property
|
|
64
|
+
def _index(
|
|
65
|
+
self,
|
|
66
|
+
) -> OrderedDict[_family_type, OrderedDict[_qualifier_type, list[Cell]]]:
|
|
67
|
+
"""
|
|
68
|
+
Returns an index of cells associated with each family and qualifier.
|
|
69
|
+
|
|
70
|
+
The index is lazily created when needed
|
|
71
|
+
|
|
72
|
+
Returns:
|
|
73
|
+
OrderedDict: Index of cells
|
|
74
|
+
"""
|
|
75
|
+
if self._index_data is None:
|
|
76
|
+
self._index_data = OrderedDict()
|
|
77
|
+
for cell in self.cells:
|
|
78
|
+
self._index_data.setdefault(cell.family, OrderedDict()).setdefault(
|
|
79
|
+
cell.qualifier, []
|
|
80
|
+
).append(cell)
|
|
81
|
+
return self._index_data
|
|
82
|
+
|
|
83
|
+
@classmethod
|
|
84
|
+
def _from_pb(cls, row_pb: RowPB) -> Row:
|
|
85
|
+
"""
|
|
86
|
+
Creates a row from a protobuf representation
|
|
87
|
+
|
|
88
|
+
Row objects are not intended to be created by users.
|
|
89
|
+
They are returned by the Bigtable backend.
|
|
90
|
+
|
|
91
|
+
Args:
|
|
92
|
+
row_pb (RowPB): Protobuf representation of the row
|
|
93
|
+
Returns:
|
|
94
|
+
Row: Row object created from the protobuf representation
|
|
95
|
+
"""
|
|
96
|
+
row_key: bytes = row_pb.key
|
|
97
|
+
cell_list: list[Cell] = []
|
|
98
|
+
for family in row_pb.families:
|
|
99
|
+
for column in family.columns:
|
|
100
|
+
for cell in column.cells:
|
|
101
|
+
new_cell = Cell(
|
|
102
|
+
value=cell.value,
|
|
103
|
+
row_key=row_key,
|
|
104
|
+
family=family.name,
|
|
105
|
+
qualifier=column.qualifier,
|
|
106
|
+
timestamp_micros=cell.timestamp_micros,
|
|
107
|
+
labels=list(cell.labels) if cell.labels else None,
|
|
108
|
+
)
|
|
109
|
+
cell_list.append(new_cell)
|
|
110
|
+
return cls(row_key, cells=cell_list)
|
|
111
|
+
|
|
112
|
+
def get_cells(
|
|
113
|
+
self, family: str | None = None, qualifier: str | bytes | None = None
|
|
114
|
+
) -> list[Cell]:
|
|
115
|
+
"""
|
|
116
|
+
Returns cells sorted in Bigtable native order:
|
|
117
|
+
- Family lexicographically ascending
|
|
118
|
+
- Qualifier ascending
|
|
119
|
+
- Timestamp in reverse chronological order
|
|
120
|
+
|
|
121
|
+
If family or qualifier not passed, will include all
|
|
122
|
+
|
|
123
|
+
Can also be accessed through indexing::
|
|
124
|
+
cells = row["family", "qualifier"]
|
|
125
|
+
cells = row["family"]
|
|
126
|
+
|
|
127
|
+
Args:
|
|
128
|
+
family: family to filter cells by
|
|
129
|
+
qualifier: qualifier to filter cells by
|
|
130
|
+
Returns:
|
|
131
|
+
list[Cell]: List of cells in the row matching the filter
|
|
132
|
+
Raises:
|
|
133
|
+
ValueError: If family or qualifier is not found in the row
|
|
134
|
+
"""
|
|
135
|
+
if family is None:
|
|
136
|
+
if qualifier is not None:
|
|
137
|
+
# get_cells(None, "qualifier") is not allowed
|
|
138
|
+
raise ValueError("Qualifier passed without family")
|
|
139
|
+
else:
|
|
140
|
+
# return all cells on get_cells()
|
|
141
|
+
return self.cells
|
|
142
|
+
if qualifier is None:
|
|
143
|
+
# return all cells in family on get_cells(family)
|
|
144
|
+
return list(self._get_all_from_family(family))
|
|
145
|
+
if isinstance(qualifier, str):
|
|
146
|
+
qualifier = qualifier.encode("utf-8")
|
|
147
|
+
# return cells in family and qualifier on get_cells(family, qualifier)
|
|
148
|
+
if family not in self._index:
|
|
149
|
+
raise ValueError(f"Family '{family}' not found in row '{self.row_key!r}'")
|
|
150
|
+
if qualifier not in self._index[family]:
|
|
151
|
+
raise ValueError(
|
|
152
|
+
f"Qualifier '{qualifier!r}' not found in family '{family}' in row '{self.row_key!r}'"
|
|
153
|
+
)
|
|
154
|
+
return self._index[family][qualifier]
|
|
155
|
+
|
|
156
|
+
def _get_all_from_family(self, family: str) -> Generator[Cell, None, None]:
|
|
157
|
+
"""
|
|
158
|
+
Returns all cells in the row for the family_id
|
|
159
|
+
|
|
160
|
+
Args:
|
|
161
|
+
family: family to filter cells by
|
|
162
|
+
Yields:
|
|
163
|
+
Cell: cells in the row for the family_id
|
|
164
|
+
Raises:
|
|
165
|
+
ValueError: If family is not found in the row
|
|
166
|
+
"""
|
|
167
|
+
if family not in self._index:
|
|
168
|
+
raise ValueError(f"Family '{family}' not found in row '{self.row_key!r}'")
|
|
169
|
+
for qualifier in self._index[family]:
|
|
170
|
+
yield from self._index[family][qualifier]
|
|
171
|
+
|
|
172
|
+
def __str__(self) -> str:
|
|
173
|
+
"""
|
|
174
|
+
Human-readable string representation::
|
|
175
|
+
|
|
176
|
+
{
|
|
177
|
+
(family='fam', qualifier=b'col'): [b'value', (+1 more),],
|
|
178
|
+
(family='fam', qualifier=b'col2'): [b'other'],
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
Returns:
|
|
182
|
+
str: Human-readable string representation of the row
|
|
183
|
+
"""
|
|
184
|
+
output = ["{"]
|
|
185
|
+
for family, qualifier in self._get_column_components():
|
|
186
|
+
cell_list = self[family, qualifier]
|
|
187
|
+
line = [f" (family={family!r}, qualifier={qualifier!r}): "]
|
|
188
|
+
if len(cell_list) == 0:
|
|
189
|
+
line.append("[],")
|
|
190
|
+
elif len(cell_list) == 1:
|
|
191
|
+
line.append(f"[{cell_list[0]}],")
|
|
192
|
+
else:
|
|
193
|
+
line.append(f"[{cell_list[0]}, (+{len(cell_list)-1} more)],")
|
|
194
|
+
output.append("".join(line))
|
|
195
|
+
output.append("}")
|
|
196
|
+
return "\n".join(output)
|
|
197
|
+
|
|
198
|
+
def __repr__(self):
|
|
199
|
+
cell_str_buffer = ["{"]
|
|
200
|
+
for family, qualifier in self._get_column_components():
|
|
201
|
+
cell_list = self[family, qualifier]
|
|
202
|
+
repr_list = [cell._to_dict() for cell in cell_list]
|
|
203
|
+
cell_str_buffer.append(f" ('{family}', {qualifier!r}): {repr_list},")
|
|
204
|
+
cell_str_buffer.append("}")
|
|
205
|
+
cell_str = "\n".join(cell_str_buffer)
|
|
206
|
+
output = f"Row(key={self.row_key!r}, cells={cell_str})"
|
|
207
|
+
return output
|
|
208
|
+
|
|
209
|
+
def _to_dict(self) -> dict[str, Any]:
|
|
210
|
+
"""
|
|
211
|
+
Returns a dictionary representation of the cell in the Bigtable Row
|
|
212
|
+
proto format
|
|
213
|
+
|
|
214
|
+
https://cloud.google.com/bigtable/docs/reference/data/rpc/google.bigtable.v2#row
|
|
215
|
+
"""
|
|
216
|
+
family_list = []
|
|
217
|
+
for family_name, qualifier_dict in self._index.items():
|
|
218
|
+
qualifier_list = []
|
|
219
|
+
for qualifier_name, cell_list in qualifier_dict.items():
|
|
220
|
+
cell_dicts = [cell._to_dict() for cell in cell_list]
|
|
221
|
+
qualifier_list.append(
|
|
222
|
+
{"qualifier": qualifier_name, "cells": cell_dicts}
|
|
223
|
+
)
|
|
224
|
+
family_list.append({"name": family_name, "columns": qualifier_list})
|
|
225
|
+
return {"key": self.row_key, "families": family_list}
|
|
226
|
+
|
|
227
|
+
# Sequence and Mapping methods
|
|
228
|
+
def __iter__(self):
|
|
229
|
+
"""
|
|
230
|
+
Allow iterating over all cells in the row
|
|
231
|
+
|
|
232
|
+
Returns:
|
|
233
|
+
Iterator: Iterator over the cells in the row
|
|
234
|
+
"""
|
|
235
|
+
return iter(self.cells)
|
|
236
|
+
|
|
237
|
+
def __contains__(self, item):
|
|
238
|
+
"""
|
|
239
|
+
Implements `in` operator
|
|
240
|
+
|
|
241
|
+
Works for both cells in the internal list, and `family` or
|
|
242
|
+
`(family, qualifier)` pairs associated with the cells
|
|
243
|
+
|
|
244
|
+
Args:
|
|
245
|
+
item: item to check for in the row
|
|
246
|
+
Returns:
|
|
247
|
+
bool: True if item is in the row, False otherwise
|
|
248
|
+
"""
|
|
249
|
+
if isinstance(item, _family_type):
|
|
250
|
+
return item in self._index
|
|
251
|
+
elif (
|
|
252
|
+
isinstance(item, tuple)
|
|
253
|
+
and isinstance(item[0], _family_type)
|
|
254
|
+
and isinstance(item[1], (bytes, str))
|
|
255
|
+
):
|
|
256
|
+
q = item[1] if isinstance(item[1], bytes) else item[1].encode("utf-8")
|
|
257
|
+
return item[0] in self._index and q in self._index[item[0]]
|
|
258
|
+
# check if Cell is in Row
|
|
259
|
+
return item in self.cells
|
|
260
|
+
|
|
261
|
+
@overload
|
|
262
|
+
def __getitem__(
|
|
263
|
+
self,
|
|
264
|
+
index: str | tuple[str, bytes | str],
|
|
265
|
+
) -> list[Cell]:
|
|
266
|
+
# overload signature for type checking
|
|
267
|
+
pass
|
|
268
|
+
|
|
269
|
+
@overload
|
|
270
|
+
def __getitem__(self, index: int) -> Cell:
|
|
271
|
+
# overload signature for type checking
|
|
272
|
+
pass
|
|
273
|
+
|
|
274
|
+
@overload
|
|
275
|
+
def __getitem__(self, index: slice) -> list[Cell]:
|
|
276
|
+
# overload signature for type checking
|
|
277
|
+
pass
|
|
278
|
+
|
|
279
|
+
def __getitem__(self, index):
|
|
280
|
+
"""
|
|
281
|
+
Implements [] indexing
|
|
282
|
+
|
|
283
|
+
Supports indexing by family, (family, qualifier) pair,
|
|
284
|
+
numerical index, and index slicing
|
|
285
|
+
"""
|
|
286
|
+
if isinstance(index, _family_type):
|
|
287
|
+
return self.get_cells(family=index)
|
|
288
|
+
elif (
|
|
289
|
+
isinstance(index, tuple)
|
|
290
|
+
and isinstance(index[0], _family_type)
|
|
291
|
+
and isinstance(index[1], (bytes, str))
|
|
292
|
+
):
|
|
293
|
+
return self.get_cells(family=index[0], qualifier=index[1])
|
|
294
|
+
elif isinstance(index, int) or isinstance(index, slice):
|
|
295
|
+
# index is int or slice
|
|
296
|
+
return self.cells[index]
|
|
297
|
+
else:
|
|
298
|
+
raise TypeError(
|
|
299
|
+
"Index must be family_id, (family_id, qualifier), int, or slice"
|
|
300
|
+
)
|
|
301
|
+
|
|
302
|
+
def __len__(self):
|
|
303
|
+
"""
|
|
304
|
+
Returns the number of cells in the row
|
|
305
|
+
|
|
306
|
+
Returns:
|
|
307
|
+
int: Number of cells in the row
|
|
308
|
+
"""
|
|
309
|
+
return len(self.cells)
|
|
310
|
+
|
|
311
|
+
def _get_column_components(self) -> list[tuple[str, bytes]]:
|
|
312
|
+
"""
|
|
313
|
+
Returns a list of (family, qualifier) pairs associated with the cells
|
|
314
|
+
|
|
315
|
+
Pairs can be used for indexing
|
|
316
|
+
|
|
317
|
+
Returns:
|
|
318
|
+
list[tuple[str, bytes]]: List of (family, qualifier) pairs
|
|
319
|
+
"""
|
|
320
|
+
return [(f, q) for f in self._index for q in self._index[f]]
|
|
321
|
+
|
|
322
|
+
def __eq__(self, other):
|
|
323
|
+
"""
|
|
324
|
+
Implements `==` operator
|
|
325
|
+
|
|
326
|
+
Returns:
|
|
327
|
+
bool: True if rows are equal, False otherwise
|
|
328
|
+
"""
|
|
329
|
+
# for performance reasons, check row metadata
|
|
330
|
+
# before checking individual cells
|
|
331
|
+
if not isinstance(other, Row):
|
|
332
|
+
return False
|
|
333
|
+
if self.row_key != other.row_key:
|
|
334
|
+
return False
|
|
335
|
+
if len(self.cells) != len(other.cells):
|
|
336
|
+
return False
|
|
337
|
+
components = self._get_column_components()
|
|
338
|
+
other_components = other._get_column_components()
|
|
339
|
+
if len(components) != len(other_components):
|
|
340
|
+
return False
|
|
341
|
+
if components != other_components:
|
|
342
|
+
return False
|
|
343
|
+
for family, qualifier in components:
|
|
344
|
+
if len(self[family, qualifier]) != len(other[family, qualifier]):
|
|
345
|
+
return False
|
|
346
|
+
# compare individual cell lists
|
|
347
|
+
if self.cells != other.cells:
|
|
348
|
+
return False
|
|
349
|
+
return True
|
|
350
|
+
|
|
351
|
+
def __ne__(self, other) -> bool:
|
|
352
|
+
"""
|
|
353
|
+
Implements `!=` operator
|
|
354
|
+
|
|
355
|
+
Returns:
|
|
356
|
+
bool: True if rows are not equal, False otherwise
|
|
357
|
+
"""
|
|
358
|
+
return not self == other
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
@total_ordering
|
|
362
|
+
class Cell:
|
|
363
|
+
"""
|
|
364
|
+
Model class for cell data
|
|
365
|
+
|
|
366
|
+
Does not represent all data contained in the cell, only data returned by a
|
|
367
|
+
query.
|
|
368
|
+
Expected to be read-only to users, and written by backend
|
|
369
|
+
|
|
370
|
+
Args:
|
|
371
|
+
value: the byte string value of the cell
|
|
372
|
+
row_key: the row key of the cell
|
|
373
|
+
family: the family associated with the cell
|
|
374
|
+
qualifier: the column qualifier associated with the cell
|
|
375
|
+
timestamp_micros: the timestamp of the cell in microseconds
|
|
376
|
+
labels: the list of labels associated with the cell
|
|
377
|
+
"""
|
|
378
|
+
|
|
379
|
+
__slots__ = (
|
|
380
|
+
"value",
|
|
381
|
+
"row_key",
|
|
382
|
+
"family",
|
|
383
|
+
"qualifier",
|
|
384
|
+
"timestamp_micros",
|
|
385
|
+
"labels",
|
|
386
|
+
)
|
|
387
|
+
|
|
388
|
+
def __init__(
|
|
389
|
+
self,
|
|
390
|
+
value: bytes,
|
|
391
|
+
row_key: bytes,
|
|
392
|
+
family: str,
|
|
393
|
+
qualifier: bytes | str,
|
|
394
|
+
timestamp_micros: int,
|
|
395
|
+
labels: list[str] | None = None,
|
|
396
|
+
):
|
|
397
|
+
# Cell objects are not intended to be constructed by users.
|
|
398
|
+
# They are returned by the Bigtable backend.
|
|
399
|
+
self.value = value
|
|
400
|
+
self.row_key = row_key
|
|
401
|
+
self.family = family
|
|
402
|
+
if isinstance(qualifier, str):
|
|
403
|
+
qualifier = qualifier.encode()
|
|
404
|
+
self.qualifier = qualifier
|
|
405
|
+
self.timestamp_micros = timestamp_micros
|
|
406
|
+
self.labels = labels if labels is not None else []
|
|
407
|
+
|
|
408
|
+
def __int__(self) -> int:
|
|
409
|
+
"""
|
|
410
|
+
Allows casting cell to int
|
|
411
|
+
Interprets value as a 64-bit big-endian signed integer, as expected by
|
|
412
|
+
ReadModifyWrite increment rule
|
|
413
|
+
|
|
414
|
+
Returns:
|
|
415
|
+
int: Value of the cell as a 64-bit big-endian signed integer
|
|
416
|
+
"""
|
|
417
|
+
return int.from_bytes(self.value, byteorder="big", signed=True)
|
|
418
|
+
|
|
419
|
+
def _to_dict(self) -> dict[str, Any]:
|
|
420
|
+
"""
|
|
421
|
+
Returns a dictionary representation of the cell in the Bigtable Cell
|
|
422
|
+
proto format
|
|
423
|
+
|
|
424
|
+
https://cloud.google.com/bigtable/docs/reference/data/rpc/google.bigtable.v2#cell
|
|
425
|
+
|
|
426
|
+
Returns:
|
|
427
|
+
dict: Dictionary representation of the cell
|
|
428
|
+
"""
|
|
429
|
+
cell_dict: dict[str, Any] = {
|
|
430
|
+
"value": self.value,
|
|
431
|
+
}
|
|
432
|
+
cell_dict["timestamp_micros"] = self.timestamp_micros
|
|
433
|
+
if self.labels:
|
|
434
|
+
cell_dict["labels"] = self.labels
|
|
435
|
+
return cell_dict
|
|
436
|
+
|
|
437
|
+
def __str__(self) -> str:
|
|
438
|
+
"""
|
|
439
|
+
Allows casting cell to str
|
|
440
|
+
Prints encoded byte string, same as printing value directly.
|
|
441
|
+
|
|
442
|
+
Returns:
|
|
443
|
+
str: Encoded byte string of the value
|
|
444
|
+
"""
|
|
445
|
+
return str(self.value)
|
|
446
|
+
|
|
447
|
+
def __repr__(self):
|
|
448
|
+
"""
|
|
449
|
+
Returns a string representation of the cell
|
|
450
|
+
|
|
451
|
+
Returns:
|
|
452
|
+
str: String representation of the cell
|
|
453
|
+
"""
|
|
454
|
+
return f"Cell(value={self.value!r}, row_key={self.row_key!r}, family='{self.family}', qualifier={self.qualifier!r}, timestamp_micros={self.timestamp_micros}, labels={self.labels})"
|
|
455
|
+
|
|
456
|
+
"""For Bigtable native ordering"""
|
|
457
|
+
|
|
458
|
+
def __lt__(self, other) -> bool:
|
|
459
|
+
"""
|
|
460
|
+
Implements `<` operator
|
|
461
|
+
|
|
462
|
+
Args:
|
|
463
|
+
other: Cell to compare with
|
|
464
|
+
Returns:
|
|
465
|
+
bool: True if this cell is less than the other cell, False otherwise
|
|
466
|
+
Raises:
|
|
467
|
+
NotImplementedError: If other is not a Cell
|
|
468
|
+
"""
|
|
469
|
+
if not isinstance(other, Cell):
|
|
470
|
+
raise NotImplementedError
|
|
471
|
+
this_ordering = (
|
|
472
|
+
self.family,
|
|
473
|
+
self.qualifier,
|
|
474
|
+
-self.timestamp_micros,
|
|
475
|
+
self.value,
|
|
476
|
+
self.labels,
|
|
477
|
+
)
|
|
478
|
+
other_ordering = (
|
|
479
|
+
other.family,
|
|
480
|
+
other.qualifier,
|
|
481
|
+
-other.timestamp_micros,
|
|
482
|
+
other.value,
|
|
483
|
+
other.labels,
|
|
484
|
+
)
|
|
485
|
+
return this_ordering < other_ordering
|
|
486
|
+
|
|
487
|
+
def __eq__(self, other) -> bool:
|
|
488
|
+
"""
|
|
489
|
+
Implements `==` operator
|
|
490
|
+
|
|
491
|
+
Args:
|
|
492
|
+
other: Cell to compare with
|
|
493
|
+
Returns:
|
|
494
|
+
bool: True if cells are equal, False otherwise
|
|
495
|
+
"""
|
|
496
|
+
if not isinstance(other, Cell):
|
|
497
|
+
return False
|
|
498
|
+
return (
|
|
499
|
+
self.row_key == other.row_key
|
|
500
|
+
and self.family == other.family
|
|
501
|
+
and self.qualifier == other.qualifier
|
|
502
|
+
and self.value == other.value
|
|
503
|
+
and self.timestamp_micros == other.timestamp_micros
|
|
504
|
+
and len(self.labels) == len(other.labels)
|
|
505
|
+
and all([label in other.labels for label in self.labels])
|
|
506
|
+
)
|
|
507
|
+
|
|
508
|
+
def __ne__(self, other) -> bool:
|
|
509
|
+
"""
|
|
510
|
+
Implements `!=` operator
|
|
511
|
+
|
|
512
|
+
Args:
|
|
513
|
+
other: Cell to compare with
|
|
514
|
+
Returns:
|
|
515
|
+
bool: True if cells are not equal, False otherwise
|
|
516
|
+
"""
|
|
517
|
+
return not self == other
|
|
518
|
+
|
|
519
|
+
def __hash__(self):
|
|
520
|
+
"""
|
|
521
|
+
Implements `hash()` function to fingerprint cell
|
|
522
|
+
|
|
523
|
+
Returns:
|
|
524
|
+
int: hash value of the cell
|
|
525
|
+
"""
|
|
526
|
+
return hash(
|
|
527
|
+
(
|
|
528
|
+
self.row_key,
|
|
529
|
+
self.family,
|
|
530
|
+
self.qualifier,
|
|
531
|
+
self.value,
|
|
532
|
+
self.timestamp_micros,
|
|
533
|
+
tuple(self.labels),
|
|
534
|
+
)
|
|
535
|
+
)
|