From 841d37c6cac3355a6bdb5cfb62f548bf490c20a9 Mon Sep 17 00:00:00 2001 From: Shuowei Li Date: Mon, 10 Aug 2026 18:33:03 +0000 Subject: [PATCH 1/2] feat(bigquery): add PendingDeprecationWarning for from_dataframe methods --- .../google/cloud/bigquery/client.py | 22 +++++++ .../tests/unit/test_client.py | 57 ++++++++++++++----- 2 files changed, 64 insertions(+), 15 deletions(-) diff --git a/packages/google-cloud-bigquery/google/cloud/bigquery/client.py b/packages/google-cloud-bigquery/google/cloud/bigquery/client.py index ce8768b68b30..7494ffb214b6 100644 --- a/packages/google-cloud-bigquery/google/cloud/bigquery/client.py +++ b/packages/google-cloud-bigquery/google/cloud/bigquery/client.py @@ -163,6 +163,16 @@ # https://github.com/googleapis/python-bigquery/issues/438 _MIN_GET_QUERY_RESULTS_TIMEOUT = 120 +_LOAD_TABLE_FROM_DATAFRAME_DEPRECATED = ( + "Loading DataFrames via google-cloud-bigquery is deprecated. " + "For direct, optimized loading, please call 'pandas_gbq.to_gbq()' directly." +) + +_INSERT_ROWS_FROM_DATAFRAME_DEPRECATED = ( + "Inserting rows from DataFrames via google-cloud-bigquery is deprecated. " + "For direct, optimized access, please call 'pandas_gbq.to_gbq()' directly." +) + TIMEOUT_HEADER = "X-Server-Timeout" @@ -2830,6 +2840,12 @@ def load_table_from_dataframe( If ``job_config`` is not an instance of :class:`~google.cloud.bigquery.job.LoadJobConfig` class. """ + warnings.warn( + _LOAD_TABLE_FROM_DATAFRAME_DEPRECATED, + PendingDeprecationWarning, + stacklevel=2, + ) + job_id = _make_job_id(job_id, job_id_prefix) if job_config is not None: @@ -3900,6 +3916,12 @@ def insert_rows_from_dataframe( Raises: ValueError: if table's schema is not set """ + warnings.warn( + _INSERT_ROWS_FROM_DATAFRAME_DEPRECATED, + PendingDeprecationWarning, + stacklevel=2, + ) + insert_results = [] chunk_count = int(math.ceil(len(dataframe) / chunk_size)) diff --git a/packages/google-cloud-bigquery/tests/unit/test_client.py b/packages/google-cloud-bigquery/tests/unit/test_client.py index 9df85b7372e5..8b56cb043109 100644 --- a/packages/google-cloud-bigquery/tests/unit/test_client.py +++ b/packages/google-cloud-bigquery/tests/unit/test_client.py @@ -6563,21 +6563,25 @@ def test_insert_rows_from_dataframe_w_explicit_none_insert_ids(self): self.assertEqual(len(error_info), 1) assert error_info[0] == [] # no chunk errors - EXPECTED_SENT_DATA = { - "rows": [ - {"insertId": None, "json": {"name": "Little One", "adult": "false"}}, - {"insertId": None, "json": {"name": "Young Gun", "adult": "true"}}, - ] - } + def test_insert_rows_from_dataframe_emits_pending_deprecation_warning(self): + pandas = pytest.importorskip("pandas") + from google.cloud.bigquery.schema import SchemaField + from google.cloud.bigquery.table import Table - actual_calls = conn.api_request.call_args_list - assert len(actual_calls) == 1 - assert actual_calls[0] == mock.call( - method="POST", - path=API_PATH, - data=EXPECTED_SENT_DATA, - timeout=DEFAULT_TIMEOUT, - ) + creds = _make_credentials() + http = object() + client = self._make_one(project=self.PROJECT, credentials=creds, _http=http) + client._connection = make_connection({}, {}) + + schema = [SchemaField("name", "STRING", mode="REQUIRED")] + table = Table(self.TABLE_REF, schema=schema) + dataframe = pandas.DataFrame([{"name": "Alice"}]) + + with pytest.warns( + PendingDeprecationWarning, + match="Inserting rows from DataFrames via google-cloud-bigquery is deprecated", + ): + client.insert_rows_from_dataframe(table, dataframe) def test_insert_rows_json_default_behavior(self): from google.cloud.bigquery.dataset import DatasetReference @@ -6841,10 +6845,10 @@ def test_insert_rows_w_wrong_arg(self): client.insert_rows_json(table, ROW) def test_insert_rows_json_w_ssl_error(self): + import requests.exceptions from google.cloud.bigquery.dataset import DatasetReference from google.cloud.bigquery.schema import SchemaField from google.cloud.bigquery.table import Table - import requests.exceptions PROJECT = "PROJECT" DS_ID = "DS_ID" @@ -9390,6 +9394,29 @@ def test_load_table_from_dataframe_w_higher_scale_decimal128_datatype(self): SchemaField("x", "BIGNUMERIC", "NULLABLE", None), ) + def test_load_table_from_dataframe_emits_pending_deprecation_warning(self): + pandas = pytest.importorskip("pandas") + pytest.importorskip("pyarrow") + + client = self._make_client() + dataframe = pandas.DataFrame({"x": [1, 2, 3]}) + + load_patch = mock.patch( + "google.cloud.bigquery.client.Client.load_table_from_file", autospec=True + ) + get_table_patch = mock.patch( + "google.cloud.bigquery.client.Client.get_table", autospec=True + ) + with ( + load_patch, + get_table_patch, + pytest.warns( + PendingDeprecationWarning, + match="Loading DataFrames via google-cloud-bigquery is deprecated", + ), + ): + client.load_table_from_dataframe(dataframe, self.TABLE_REF) + # With autodetect specified, we pass the value as is. For more info, see # https://github.com/googleapis/python-bigquery/issues/1228#issuecomment-1910946297 def test_load_table_from_json_basic_use(self): From e2cabc1c87bd68239e9618214952f7b461af23c6 Mon Sep 17 00:00:00 2001 From: Shuowei Li Date: Mon, 10 Aug 2026 19:58:10 +0000 Subject: [PATCH 2/2] fix(bigquery): address review comments in test_client --- .../tests/unit/test_client.py | 26 ++++++++++++++----- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/packages/google-cloud-bigquery/tests/unit/test_client.py b/packages/google-cloud-bigquery/tests/unit/test_client.py index 8b56cb043109..d9c7fbbfbe5a 100644 --- a/packages/google-cloud-bigquery/tests/unit/test_client.py +++ b/packages/google-cloud-bigquery/tests/unit/test_client.py @@ -6563,6 +6563,22 @@ def test_insert_rows_from_dataframe_w_explicit_none_insert_ids(self): self.assertEqual(len(error_info), 1) assert error_info[0] == [] # no chunk errors + EXPECTED_SENT_DATA = { + "rows": [ + {"insertId": None, "json": {"name": "Little One", "adult": "false"}}, + {"insertId": None, "json": {"name": "Young Gun", "adult": "true"}}, + ] + } + + actual_calls = conn.api_request.call_args_list + assert len(actual_calls) == 1 + assert actual_calls[0] == mock.call( + method="POST", + path=API_PATH, + data=EXPECTED_SENT_DATA, + timeout=DEFAULT_TIMEOUT, + ) + def test_insert_rows_from_dataframe_emits_pending_deprecation_warning(self): pandas = pytest.importorskip("pandas") from google.cloud.bigquery.schema import SchemaField @@ -9407,13 +9423,9 @@ def test_load_table_from_dataframe_emits_pending_deprecation_warning(self): get_table_patch = mock.patch( "google.cloud.bigquery.client.Client.get_table", autospec=True ) - with ( - load_patch, - get_table_patch, - pytest.warns( - PendingDeprecationWarning, - match="Loading DataFrames via google-cloud-bigquery is deprecated", - ), + with load_patch, get_table_patch, pytest.warns( + PendingDeprecationWarning, + match="Loading DataFrames via google-cloud-bigquery is deprecated", ): client.load_table_from_dataframe(dataframe, self.TABLE_REF)