Skip to content

Commit 2ae1121

Browse files
committed
Merge remote-tracking branch 'origin/main' into b323176126-pandas-gbq
2 parents 1606cd6 + 6cbd5c0 commit 2ae1121

File tree

13 files changed

+134
-101
lines changed

13 files changed

+134
-101
lines changed

.kokoro/docker/docs/requirements.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
#
55
# pip-compile --allow-unsafe --generate-hashes synthtool/gcp/templates/python_library/.kokoro/docker/docs/requirements.in
66
#
7-
argcomplete==3.5.2 \
8-
--hash=sha256:036d020d79048a5d525bc63880d7a4b8d1668566b8a76daf1144c0bbe0f63472 \
9-
--hash=sha256:23146ed7ac4403b70bd6026402468942ceba34a6732255b9edf5b7354f68a6bb
7+
argcomplete==3.5.3 \
8+
--hash=sha256:2ab2c4a215c59fd6caaff41a869480a23e8f6a5f910b266c1808037f4e375b61 \
9+
--hash=sha256:c12bf50eded8aebb298c7b7da7a5ff3ee24dffd9f5281867dfe1424b58c55392
1010
# via nox
1111
colorlog==6.9.0 \
1212
--hash=sha256:5906e71acd67cb07a71e779c47c4bcb45fb8c2993eebe9e5adcd6a6f1b283eff \

google/cloud/bigquery/schema.py

Lines changed: 25 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@
1616

1717
import collections
1818
import enum
19-
from typing import Any, Dict, Iterable, Optional, Union, cast
19+
from typing import Any, cast, Dict, Iterable, Optional, Union
2020

21+
from google.cloud.bigquery import _helpers
2122
from google.cloud.bigquery import standard_sql
2223
from google.cloud.bigquery.enums import StandardSqlTypeNames
2324

@@ -203,15 +204,8 @@ def __init__(
203204
self._properties["rangeElementType"] = {"type": range_element_type}
204205
if isinstance(range_element_type, FieldElementType):
205206
self._properties["rangeElementType"] = range_element_type.to_api_repr()
206-
207-
self._fields = tuple(fields)
208-
209-
@staticmethod
210-
def __get_int(api_repr, name):
211-
v = api_repr.get(name, _DEFAULT_VALUE)
212-
if v is not _DEFAULT_VALUE:
213-
v = int(v)
214-
return v
207+
if fields: # Don't set the property if it's not set.
208+
self._properties["fields"] = [field.to_api_repr() for field in fields]
215209

216210
@classmethod
217211
def from_api_repr(cls, api_repr: dict) -> "SchemaField":
@@ -225,43 +219,19 @@ def from_api_repr(cls, api_repr: dict) -> "SchemaField":
225219
Returns:
226220
google.cloud.bigquery.schema.SchemaField: The ``SchemaField`` object.
227221
"""
228-
field_type = api_repr["type"].upper()
229-
230-
# Handle optional properties with default values
231-
mode = api_repr.get("mode", "NULLABLE")
232-
description = api_repr.get("description", _DEFAULT_VALUE)
233-
fields = api_repr.get("fields", ())
234-
policy_tags = api_repr.get("policyTags", _DEFAULT_VALUE)
222+
placeholder = cls("this_will_be_replaced", "PLACEHOLDER")
235223

236-
default_value_expression = api_repr.get("defaultValueExpression", None)
224+
# Note: we don't make a copy of api_repr because this can cause
225+
# unnecessary slowdowns, especially on deeply nested STRUCT / RECORD
226+
# fields. See https://github.com/googleapis/python-bigquery/issues/6
227+
placeholder._properties = api_repr
237228

238-
if policy_tags is not None and policy_tags is not _DEFAULT_VALUE:
239-
policy_tags = PolicyTagList.from_api_repr(policy_tags)
240-
241-
if api_repr.get("rangeElementType"):
242-
range_element_type = cast(dict, api_repr.get("rangeElementType"))
243-
element_type = range_element_type.get("type")
244-
else:
245-
element_type = None
246-
247-
return cls(
248-
field_type=field_type,
249-
fields=[cls.from_api_repr(f) for f in fields],
250-
mode=mode.upper(),
251-
default_value_expression=default_value_expression,
252-
description=description,
253-
name=api_repr["name"],
254-
policy_tags=policy_tags,
255-
precision=cls.__get_int(api_repr, "precision"),
256-
scale=cls.__get_int(api_repr, "scale"),
257-
max_length=cls.__get_int(api_repr, "maxLength"),
258-
range_element_type=element_type,
259-
)
229+
return placeholder
260230

261231
@property
262232
def name(self):
263233
"""str: The name of the field."""
264-
return self._properties["name"]
234+
return self._properties.get("name", "")
265235

266236
@property
267237
def field_type(self):
@@ -270,7 +240,10 @@ def field_type(self):
270240
See:
271241
https://cloud.google.com/bigquery/docs/reference/rest/v2/tables#TableFieldSchema.FIELDS.type
272242
"""
273-
return self._properties["type"]
243+
type_ = self._properties.get("type")
244+
if type_ is None: # Shouldn't happen, but some unit tests do this.
245+
return None
246+
return cast(str, type_).upper()
274247

275248
@property
276249
def mode(self):
@@ -279,7 +252,7 @@ def mode(self):
279252
See:
280253
https://cloud.google.com/bigquery/docs/reference/rest/v2/tables#TableFieldSchema.FIELDS.mode
281254
"""
282-
return self._properties.get("mode")
255+
return cast(str, self._properties.get("mode", "NULLABLE")).upper()
283256

284257
@property
285258
def is_nullable(self):
@@ -299,17 +272,17 @@ def description(self):
299272
@property
300273
def precision(self):
301274
"""Optional[int]: Precision (number of digits) for the NUMERIC field."""
302-
return self._properties.get("precision")
275+
return _helpers._int_or_none(self._properties.get("precision"))
303276

304277
@property
305278
def scale(self):
306279
"""Optional[int]: Scale (digits after decimal) for the NUMERIC field."""
307-
return self._properties.get("scale")
280+
return _helpers._int_or_none(self._properties.get("scale"))
308281

309282
@property
310283
def max_length(self):
311284
"""Optional[int]: Maximum length for the STRING or BYTES field."""
312-
return self._properties.get("maxLength")
285+
return _helpers._int_or_none(self._properties.get("maxLength"))
313286

314287
@property
315288
def range_element_type(self):
@@ -329,7 +302,7 @@ def fields(self):
329302
330303
Must be empty unset if ``field_type`` is not 'RECORD'.
331304
"""
332-
return self._fields
305+
return tuple(_to_schema_fields(self._properties.get("fields", [])))
333306

334307
@property
335308
def policy_tags(self):
@@ -345,15 +318,10 @@ def to_api_repr(self) -> dict:
345318
Returns:
346319
Dict: A dictionary representing the SchemaField in a serialized form.
347320
"""
348-
answer = self._properties.copy()
349-
350-
# If this is a RECORD type, then sub-fields are also included,
351-
# add this to the serialized representation.
352-
if self.field_type.upper() in _STRUCT_TYPES:
353-
answer["fields"] = [f.to_api_repr() for f in self.fields]
354-
355-
# Done; return the serialized dictionary.
356-
return answer
321+
# Note: we don't make a copy of _properties because this can cause
322+
# unnecessary slowdowns, especially on deeply nested STRUCT / RECORD
323+
# fields. See https://github.com/googleapis/python-bigquery/issues/6
324+
return self._properties
357325

358326
def _key(self):
359327
"""A tuple key that uniquely describes this field.
@@ -389,7 +357,7 @@ def _key(self):
389357
self.mode.upper(), # pytype: disable=attribute-error
390358
self.default_value_expression,
391359
self.description,
392-
self._fields,
360+
self.fields,
393361
policy_tags,
394362
)
395363

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
google-cloud-testutils==1.4.0
1+
google-cloud-testutils==1.5.0
22
pytest===7.4.4; python_version == '3.7'
3-
pytest==8.3.3; python_version >= '3.8'
3+
pytest==8.3.4; python_version >= '3.8'
44
mock==5.1.0
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
pytest===7.4.4; python_version == '3.7'
2-
pytest==8.3.3; python_version >= '3.8'
2+
pytest==8.3.4; python_version >= '3.8'
33
mock==5.1.0

samples/geography/requirements.txt

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,22 @@
1-
attrs==24.2.0
2-
certifi==2024.8.30
1+
attrs===24.2.0; python_version == '3.7'
2+
attrs==24.3.0; python_version >= '3.8'
3+
certifi==2024.12.14
34
cffi===1.15.1; python_version == '3.7'
45
cffi==1.17.1; python_version >= '3.8'
5-
charset-normalizer==3.4.0
6-
click==8.1.7
6+
charset-normalizer==3.4.1
7+
click==8.1.8
78
click-plugins==1.1.1
89
cligj==0.7.2
910
dataclasses==0.8; python_version < '3.7'
1011
db-dtypes==1.3.1
1112
Fiona===1.9.6; python_version == '3.7'
1213
Fiona==1.10.1; python_version >= '3.8'
13-
geojson==3.1.0
14+
geojson==3.2.0
1415
geopandas===0.10.2; python_version == '3.7'
1516
geopandas===0.13.2; python_version == '3.8'
1617
geopandas==1.0.1; python_version >= '3.9'
17-
google-api-core==2.23.0
18-
google-auth==2.36.0
18+
google-api-core==2.24.0
19+
google-auth==2.37.0
1920
google-cloud-bigquery==3.27.0
2021
google-cloud-bigquery-storage==2.27.0
2122
google-cloud-core==2.4.1
@@ -24,7 +25,7 @@ google-crc32c==1.6.0; python_version >= '3.9'
2425
google-resumable-media==2.7.2
2526
googleapis-common-protos==1.66.0
2627
grpcio===1.62.2; python_version == '3.7'
27-
grpcio==1.68.0; python_version >= '3.8'
28+
grpcio==1.68.1; python_version >= '3.8'
2829
idna==3.10
2930
munch==4.0.0
3031
mypy-extensions==1.0.0
@@ -44,7 +45,7 @@ pyasn1-modules==0.4.1; python_version >= '3.8'
4445
pycparser===2.21; python_version == '3.7'
4546
pycparser==2.22; python_version >= '3.8'
4647
pyparsing===3.1.4; python_version < '3.9'
47-
pyparsing==3.2.0; python_version >= '3.9'
48+
pyparsing==3.2.1; python_version >= '3.9'
4849
python-dateutil==2.9.0.post0
4950
pytz==2024.2
5051
PyYAML===6.0.1; python_version == '3.7'
@@ -53,9 +54,10 @@ requests==2.31.0; python_version == '3.7'
5354
requests==2.32.3; python_version >= '3.8'
5455
rsa==4.9
5556
Shapely==2.0.6
56-
six==1.16.0
57+
six==1.17.0
5758
typing-extensions===4.7.1; python_version == '3.7'
5859
typing-extensions==4.12.2; python_version >= '3.8'
5960
typing-inspect==0.9.0
6061
urllib3===1.26.18; python_version == '3.7'
61-
urllib3==2.2.3; python_version >= '3.8'
62+
urllib3===2.2.3; python_version == '3.8'
63+
urllib3==2.3.0; python_version >= '3.9'
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
google-cloud-testutils==1.4.0
1+
google-cloud-testutils==1.5.0
22
pytest===7.4.4; python_version == '3.7'
3-
pytest==8.3.3; python_version >= '3.8'
3+
pytest==8.3.4; python_version >= '3.8'
44
mock==5.1.0

samples/magics/requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
bigquery_magics==0.4.0
1+
bigquery_magics==0.5.0
22
db-dtypes==1.3.1
33
google.cloud.bigquery==3.27.0
44
google-cloud-bigquery-storage==2.27.0
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
google-cloud-testutils==1.4.0
1+
google-cloud-testutils==1.5.0
22
pytest===7.4.4; python_version == '3.7'
3-
pytest==8.3.3; python_version >= '3.8'
3+
pytest==8.3.4; python_version >= '3.8'
44
mock==5.1.0

samples/notebooks/requirements.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
bigquery-magics==0.4.0
1+
bigquery-magics==0.5.0
22
db-dtypes==1.3.1
33
google-cloud-bigquery==3.27.0
44
google-cloud-bigquery-storage==2.27.0
@@ -7,7 +7,8 @@ ipython===8.0.1; python_version == '3.8'
77
ipython===8.18.1; python_version >= '3.9'
88
matplotlib===3.5.3; python_version == '3.7'
99
matplotlib===3.7.4; python_version == '3.8'
10-
matplotlib==3.9.2; python_version >= '3.9'
10+
matplotlib===3.9.2; python_version == '3.9'
11+
matplotlib==3.10.0; python_version >= '3.10'
1112
pandas===1.3.5; python_version == '3.7'
1213
pandas===2.0.3; python_version == '3.8'
1314
pandas==2.2.3; python_version >= '3.9'
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# samples/snippets should be runnable with no "extras"
2-
google-cloud-testutils==1.4.0
2+
google-cloud-testutils==1.5.0
33
pytest===7.4.4; python_version == '3.7'
4-
pytest==8.3.3; python_version >= '3.8'
4+
pytest==8.3.4; python_version >= '3.8'
55
mock==5.1.0

0 commit comments

Comments
 (0)