Skip to content

Commit f61f3ce

Browse files
authored
Merge branch 'main' into test-xdist-experimentation
2 parents fc87d78 + b162288 commit f61f3ce

File tree

10 files changed

+55
-14
lines changed

10 files changed

+55
-14
lines changed

.github/.OwlBot.lock.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,5 @@
1313
# limitations under the License.
1414
docker:
1515
image: gcr.io/cloud-devrel-public-resources/owlbot-python:latest
16-
digest: sha256:5581906b957284864632cde4e9c51d1cc66b0094990b27e689132fe5cd036046
17-
# created: 2025-03-07
16+
digest: sha256:a7aef70df5f13313ddc027409fc8f3151422ec2a57ac8730fce8fa75c060d5bb
17+
# created: 2025-04-10T17:00:10.042601326Z

google/cloud/bigquery/_job_helpers.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,7 @@ def _supported_by_jobs_query(request_body: Dict[str, Any]) -> bool:
564564
"maximumBytesBilled",
565565
"requestId",
566566
"createSession",
567+
"writeIncrementalResults",
567568
}
568569

569570
unsupported_keys = request_keys - keys_allowlist

google/cloud/bigquery/job/query.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -674,6 +674,21 @@ def write_disposition(self):
674674
def write_disposition(self, value):
675675
self._set_sub_prop("writeDisposition", value)
676676

677+
@property
678+
def write_incremental_results(self) -> Optional[bool]:
679+
"""This is only supported for a SELECT query using a temporary table.
680+
681+
If set, the query is allowed to write results incrementally to the temporary result
682+
table. This may incur a performance penalty. This option cannot be used with Legacy SQL.
683+
684+
This feature is not generally available.
685+
"""
686+
return self._get_sub_prop("writeIncrementalResults")
687+
688+
@write_incremental_results.setter
689+
def write_incremental_results(self, value):
690+
self._set_sub_prop("writeIncrementalResults", value)
691+
677692
@property
678693
def table_definitions(self):
679694
"""Dict[str, google.cloud.bigquery.external_config.ExternalConfig]:

google/cloud/bigquery/table.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1873,6 +1873,11 @@ def total_bytes_processed(self) -> Optional[int]:
18731873
"""total bytes processed from job statistics, if present."""
18741874
return self._total_bytes_processed
18751875

1876+
@property
1877+
def page_size(self) -> Optional[int]:
1878+
"""The maximum number of rows in each page of results from this request, if present."""
1879+
return self._page_size
1880+
18761881
def _is_almost_completely_cached(self):
18771882
"""Check if all results are completely cached.
18781883
@@ -1924,7 +1929,7 @@ def _should_use_bqstorage(self, bqstorage_client, create_bqstorage_client):
19241929
if self._is_almost_completely_cached():
19251930
return False
19261931

1927-
if self.max_results is not None:
1932+
if self.max_results is not None or self.page_size is not None:
19281933
return False
19291934

19301935
try:
@@ -1994,7 +1999,9 @@ def _maybe_warn_max_results(
19941999
bqstorage_client:
19952000
The BigQuery Storage client intended to use for downloading result rows.
19962001
"""
1997-
if bqstorage_client is not None and self.max_results is not None:
2002+
if bqstorage_client is not None and (
2003+
self.max_results is not None or self.page_size is not None
2004+
):
19982005
warnings.warn(
19992006
"Cannot use bqstorage_client if max_results is set, "
20002007
"reverting to fetching data with the REST endpoint.",

owlbot.py

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -130,14 +130,6 @@
130130
'ALL_VERSIONS = ["3.9", "3.10", "3.11", "3.12", "3.13"]',
131131
)
132132

133-
134-
# ----------------------------------------------------------------------------
135-
# pytype-related changes
136-
# ----------------------------------------------------------------------------
137-
138-
# Add .pytype to .gitignore
139-
s.replace(".gitignore", r"\.pytest_cache", "\\g<0>\n.pytype")
140-
141133
s.shell.run(["nox", "-s", "blacken"], hide_output=False)
142134
for noxfile in REPO_ROOT.glob("samples/**/noxfile.py"):
143135
s.shell.run(["nox", "-s", "blacken"], cwd=noxfile.parent, hide_output=False)

samples/geography/requirements.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,9 @@ pytz==2025.2
3434
PyYAML==6.0.2
3535
requests==2.32.3
3636
rsa==4.9
37-
Shapely==2.0.7
37+
Shapely===2.0.7; python_version == '3.9'
38+
Shapely==2.1.0; python_version >= '3.10'
3839
six==1.17.0
39-
typing-extensions==4.13.0
40+
typing-extensions==4.13.1
4041
typing-inspect==0.9.0
4142
urllib3==2.3.0

tests/unit/job/test_query_config.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,11 @@ def test_connection_properties(self):
167167
self.assertEqual(config.connection_properties[1].key, "time_zone")
168168
self.assertEqual(config.connection_properties[1].value, "America/Chicago")
169169

170+
def test_incremental_results(self):
171+
config = self._get_target_class()()
172+
config.write_incremental_results = True
173+
self.assertEqual(config.write_incremental_results, True)
174+
170175
def test_create_session(self):
171176
config = self._get_target_class()()
172177
self.assertIsNone(config.create_session)

tests/unit/test__job_helpers.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,13 @@ def make_query_response(
194194
make_query_request({"maximumBytesBilled": "987654"}),
195195
id="job_config-with-maximum_bytes_billed",
196196
),
197+
pytest.param(
198+
job_query.QueryJobConfig(
199+
write_incremental_results=True,
200+
),
201+
make_query_request({"writeIncrementalResults": True}),
202+
id="job_config-with-incremental-results",
203+
),
197204
),
198205
)
199206
def test__to_query_request(job_config, expected):
@@ -1141,6 +1148,11 @@ def test_make_job_id_w_job_id_overrides_prefix():
11411148
False,
11421149
id="priority=BATCH",
11431150
),
1151+
pytest.param(
1152+
job_query.QueryJobConfig(write_incremental_results=True),
1153+
True,
1154+
id="write_incremental_results",
1155+
),
11441156
),
11451157
)
11461158
def test_supported_by_jobs_query_from_queryjobconfig(

tests/unit/test_dbapi_cursor.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ def _mock_rows(
161161
mock_rows,
162162
)
163163
mock_rows.max_results = None
164+
mock_rows.page_size = None
164165
type(mock_rows).job_id = mock.PropertyMock(return_value="test-job-id")
165166
type(mock_rows).location = mock.PropertyMock(return_value="test-location")
166167
type(mock_rows).num_dml_affected_rows = mock.PropertyMock(

tests/unit/test_table.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2693,6 +2693,13 @@ def test__should_use_bqstorage_returns_false_if_max_results_set(self):
26932693
)
26942694
self.assertFalse(result)
26952695

2696+
def test__should_use_bqstorage_returns_false_if_page_size_set(self):
2697+
iterator = self._make_one(page_size=10, first_page_response=None) # not cached
2698+
result = iterator._should_use_bqstorage(
2699+
bqstorage_client=None, create_bqstorage_client=True
2700+
)
2701+
self.assertFalse(result)
2702+
26962703
def test__should_use_bqstorage_returns_false_w_warning_if_missing_dependency(self):
26972704
iterator = self._make_one(first_page_response=None) # not cached
26982705

0 commit comments

Comments
 (0)