6969 import geopandas
7070 import pyarrow
7171 from google .cloud import bigquery_storage
72+ from google .cloud .bigquery .dataset import DatasetReference
7273
7374
7475_NO_PANDAS_ERROR = (
@@ -126,45 +127,93 @@ def _view_use_legacy_sql_getter(table):
126127 return True
127128
128129
129- class TableReference ( object ) :
130- """TableReferences are pointers to tables.
130+ class _TableBase :
131+ """Base class for Table-related classes with common functionality."""
131132
132- See
133- https://cloud.google.com/bigquery/docs/reference/rest/v2/tables#tablereference
134-
135- Args:
136- dataset_ref (google.cloud.bigquery.dataset.DatasetReference):
137- A pointer to the dataset
138- table_id (str): The ID of the table
139- """
133+ _PROPERTY_TO_API_FIELD = {
134+ "dataset_id" : ["tableReference" , "datasetId" ],
135+ "project" : ["tableReference" , "projectId" ],
136+ "table_id" : ["tableReference" , "tableId" ],
137+ }
140138
141- def __init__ (self , dataset_ref , table_id ):
142- self ._project = dataset_ref .project
143- self ._dataset_id = dataset_ref .dataset_id
144- self ._table_id = table_id
139+ def __init__ (self ):
140+ self ._properties = {}
145141
146142 @property
147- def project (self ):
148- """str: Project bound to the table"""
149- return self ._project
143+ def project (self ) -> str :
144+ """Project bound to the table."""
145+ return _helpers ._get_sub_prop (
146+ self ._properties , self ._PROPERTY_TO_API_FIELD ["project" ]
147+ )
150148
151149 @property
152- def dataset_id (self ):
153- """str: ID of dataset containing the table."""
154- return self ._dataset_id
150+ def dataset_id (self ) -> str :
151+ """ID of dataset containing the table."""
152+ return _helpers ._get_sub_prop (
153+ self ._properties , self ._PROPERTY_TO_API_FIELD ["dataset_id" ]
154+ )
155155
156156 @property
157- def table_id (self ):
158- """str: The table ID."""
159- return self ._table_id
157+ def table_id (self ) -> str :
158+ """The table ID."""
159+ return _helpers ._get_sub_prop (
160+ self ._properties , self ._PROPERTY_TO_API_FIELD ["table_id" ]
161+ )
160162
161163 @property
162- def path (self ):
163- """str: URL path for the table's APIs."""
164- return "/projects/%s/datasets/%s/tables/%s" % (
165- self ._project ,
166- self ._dataset_id ,
167- self ._table_id ,
164+ def path (self ) -> str :
165+ """URL path for the table's APIs."""
166+ return (
167+ f"/projects/{ self .project } /datasets/{ self .dataset_id } "
168+ f"/tables/{ self .table_id } "
169+ )
170+
171+ def __eq__ (self , other ):
172+ if isinstance (other , _TableBase ):
173+ return (
174+ self .project == other .project
175+ and self .dataset_id == other .dataset_id
176+ and self .table_id == other .table_id
177+ )
178+ else :
179+ return NotImplemented
180+
181+ def __hash__ (self ):
182+ return hash ((self .project , self .dataset_id , self .table_id ))
183+
184+
185+ class TableReference (_TableBase ):
186+ """TableReferences are pointers to tables.
187+
188+ See
189+ https://cloud.google.com/bigquery/docs/reference/rest/v2/tables#tablereference
190+
191+ Args:
192+ dataset_ref: A pointer to the dataset
193+ table_id: The ID of the table
194+ """
195+
196+ _PROPERTY_TO_API_FIELD = {
197+ "dataset_id" : "datasetId" ,
198+ "project" : "projectId" ,
199+ "table_id" : "tableId" ,
200+ }
201+
202+ def __init__ (self , dataset_ref : "DatasetReference" , table_id : str ):
203+ self ._properties = {}
204+
205+ _helpers ._set_sub_prop (
206+ self ._properties ,
207+ self ._PROPERTY_TO_API_FIELD ["project" ],
208+ dataset_ref .project ,
209+ )
210+ _helpers ._set_sub_prop (
211+ self ._properties ,
212+ self ._PROPERTY_TO_API_FIELD ["dataset_id" ],
213+ dataset_ref .dataset_id ,
214+ )
215+ _helpers ._set_sub_prop (
216+ self ._properties , self ._PROPERTY_TO_API_FIELD ["table_id" ], table_id ,
168217 )
169218
170219 @classmethod
@@ -233,11 +282,7 @@ def to_api_repr(self) -> dict:
233282 Returns:
234283 Dict[str, object]: Table reference represented as an API resource
235284 """
236- return {
237- "projectId" : self ._project ,
238- "datasetId" : self ._dataset_id ,
239- "tableId" : self ._table_id ,
240- }
285+ return copy .deepcopy (self ._properties )
241286
242287 def to_bqstorage (self ) -> str :
243288 """Construct a BigQuery Storage API representation of this table.
@@ -257,54 +302,25 @@ def to_bqstorage(self) -> str:
257302 str: A reference to this table in the BigQuery Storage API.
258303 """
259304
260- table_id , _ , _ = self ._table_id .partition ("@" )
305+ table_id , _ , _ = self .table_id .partition ("@" )
261306 table_id , _ , _ = table_id .partition ("$" )
262307
263- table_ref = "projects/{}/datasets/{}/tables/{}" . format (
264- self ._project , self ._dataset_id , table_id ,
308+ table_ref = (
309+ f"projects/ { self .project } /datasets/ { self .dataset_id } /tables/ { table_id } "
265310 )
266-
267311 return table_ref
268312
269- def _key (self ):
270- """A tuple key that uniquely describes this field.
271-
272- Used to compute this instance's hashcode and evaluate equality.
273-
274- Returns:
275- Tuple[str]: The contents of this :class:`DatasetReference`.
276- """
277- return (self ._project , self ._dataset_id , self ._table_id )
278-
279- def __eq__ (self , other ):
280- if isinstance (other , (Table , TableListItem )):
281- return (
282- self .project == other .project
283- and self .dataset_id == other .dataset_id
284- and self .table_id == other .table_id
285- )
286- elif isinstance (other , TableReference ):
287- return self ._key () == other ._key ()
288- else :
289- return NotImplemented
290-
291- def __ne__ (self , other ):
292- return not self == other
293-
294- def __hash__ (self ):
295- return hash (self ._key ())
296-
297313 def __str__ (self ):
298314 return f"{ self .project } .{ self .dataset_id } .{ self .table_id } "
299315
300316 def __repr__ (self ):
301317 from google .cloud .bigquery .dataset import DatasetReference
302318
303- dataset_ref = DatasetReference (self ._project , self ._dataset_id )
304- return "TableReference({}, '{}')" . format ( repr ( dataset_ref ), self . _table_id )
319+ dataset_ref = DatasetReference (self .project , self .dataset_id )
320+ return f "TableReference({ dataset_ref !r } , '{ self . table_id } ')"
305321
306322
307- class Table (object ):
323+ class Table (_TableBase ):
308324 """Tables represent a set of rows whose values correspond to a schema.
309325
310326 See
@@ -325,9 +341,9 @@ class Table(object):
325341 """
326342
327343 _PROPERTY_TO_API_FIELD = {
344+ ** _TableBase ._PROPERTY_TO_API_FIELD ,
328345 "clustering_fields" : "clustering" ,
329346 "created" : "creationTime" ,
330- "dataset_id" : ["tableReference" , "datasetId" ],
331347 "description" : "description" ,
332348 "encryption_configuration" : "encryptionConfiguration" ,
333349 "etag" : "etag" ,
@@ -346,14 +362,12 @@ class Table(object):
346362 "num_rows" : "numRows" ,
347363 "partition_expiration" : "timePartitioning" ,
348364 "partitioning_type" : "timePartitioning" ,
349- "project" : ["tableReference" , "projectId" ],
350365 "range_partitioning" : "rangePartitioning" ,
351366 "time_partitioning" : "timePartitioning" ,
352367 "schema" : "schema" ,
353368 "snapshot_definition" : "snapshotDefinition" ,
354369 "streaming_buffer" : "streamingBuffer" ,
355370 "self_link" : "selfLink" ,
356- "table_id" : ["tableReference" , "tableId" ],
357371 "time_partitioning" : "timePartitioning" ,
358372 "type" : "type" ,
359373 "view_use_legacy_sql" : "view" ,
@@ -368,38 +382,8 @@ def __init__(self, table_ref, schema=None):
368382 if schema is not None :
369383 self .schema = schema
370384
371- @property
372- def project (self ):
373- """str: Project bound to the table."""
374- return _helpers ._get_sub_prop (
375- self ._properties , self ._PROPERTY_TO_API_FIELD ["project" ]
376- )
377-
378- @property
379- def dataset_id (self ):
380- """str: ID of dataset containing the table."""
381- return _helpers ._get_sub_prop (
382- self ._properties , self ._PROPERTY_TO_API_FIELD ["dataset_id" ]
383- )
384-
385- @property
386- def table_id (self ):
387- """str: ID of the table."""
388- return _helpers ._get_sub_prop (
389- self ._properties , self ._PROPERTY_TO_API_FIELD ["table_id" ]
390- )
391-
392385 reference = property (_reference_getter )
393386
394- @property
395- def path (self ):
396- """str: URL path for the table's APIs."""
397- return "/projects/%s/datasets/%s/tables/%s" % (
398- self .project ,
399- self .dataset_id ,
400- self .table_id ,
401- )
402-
403387 @property
404388 def require_partition_filter (self ):
405389 """bool: If set to true, queries over the partitioned table require a
@@ -1040,29 +1024,11 @@ def _build_resource(self, filter_fields):
10401024 """Generate a resource for ``update``."""
10411025 return _helpers ._build_resource_from_properties (self , filter_fields )
10421026
1043- def __eq__ (self , other ):
1044- if isinstance (other , Table ):
1045- return (
1046- self ._properties ["tableReference" ]
1047- == other ._properties ["tableReference" ]
1048- )
1049- elif isinstance (other , (TableReference , TableListItem )):
1050- return (
1051- self .project == other .project
1052- and self .dataset_id == other .dataset_id
1053- and self .table_id == other .table_id
1054- )
1055- else :
1056- return NotImplemented
1057-
1058- def __hash__ (self ):
1059- return hash ((self .project , self .dataset_id , self .table_id ))
1060-
10611027 def __repr__ (self ):
10621028 return "Table({})" .format (repr (self .reference ))
10631029
10641030
1065- class TableListItem (object ):
1031+ class TableListItem (_TableBase ):
10661032 """A read-only table resource from a list operation.
10671033
10681034 For performance reasons, the BigQuery API only includes some of the table
@@ -1126,21 +1092,6 @@ def expires(self):
11261092 1000.0 * float (expiration_time )
11271093 )
11281094
1129- @property
1130- def project (self ):
1131- """str: Project bound to the table."""
1132- return self ._properties ["tableReference" ]["projectId" ]
1133-
1134- @property
1135- def dataset_id (self ):
1136- """str: ID of dataset containing the table."""
1137- return self ._properties ["tableReference" ]["datasetId" ]
1138-
1139- @property
1140- def table_id (self ):
1141- """str: ID of the table."""
1142- return self ._properties ["tableReference" ]["tableId" ]
1143-
11441095 reference = property (_reference_getter )
11451096
11461097 @property
@@ -1276,19 +1227,6 @@ def to_api_repr(self) -> dict:
12761227 """
12771228 return copy .deepcopy (self ._properties )
12781229
1279- def __eq__ (self , other ):
1280- if isinstance (other , (Table , TableReference , TableListItem )):
1281- return (
1282- self .project == other .project
1283- and self .dataset_id == other .dataset_id
1284- and self .table_id == other .table_id
1285- )
1286- else :
1287- return NotImplemented
1288-
1289- def __hash__ (self ):
1290- return hash ((self .project , self .dataset_id , self .table_id ))
1291-
12921230
12931231def _row_from_mapping (mapping , schema ):
12941232 """Convert a mapping to a row tuple using the schema.
0 commit comments