Skip to content

Commit dbaf8f5

Browse files
feat(bigquery-magics): deprecate --engine=bigframes, run %load_ext bigframes and use %%bqsql magics instead (#16573)
Towards internal issue b/500399391 🦕 --------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
1 parent 32d9f7e commit dbaf8f5

File tree

3 files changed

+110
-6
lines changed

3 files changed

+110
-6
lines changed

packages/bigquery-magics/bigquery_magics/bigquery.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,10 @@
7878
the variable name (ex. ``$my_dict_var``). See ``In[6]`` and ``In[7]``
7979
in the Examples section below.
8080
* ``--engine <engine>`` (Optional[line argument]):
81-
Set the execution engine, either 'pandas' (default) or 'bigframes'
82-
(experimental).
81+
[Deprecated] Set the execution engine, either 'pandas' (default) or
82+
'bigframes'.
83+
Please use ``%load_ext bigframes`` and the ``%%bqsql`` magic instead.
84+
See: https://dataframes.bigquery.dev/notebooks/getting_started/magics.html
8385
* ``--pyformat`` (Optional[line argument]):
8486
Warning! Do not use with user-provided values.
8587
This doesn't escape values. Use --params instead for proper SQL escaping.
@@ -397,8 +399,10 @@ def _create_dataset_if_necessary(client, dataset_id):
397399
type=str,
398400
default=None,
399401
help=(
400-
"Set the execution engine, either 'pandas' or 'bigframes'."
401-
"Defaults to engine set in the query setting in console."
402+
"[Deprecated] Set the execution engine, either 'pandas' or 'bigframes'. "
403+
"Defaults to engine set in the query setting in console. "
404+
"Please use %%load_ext bigframes and the %%%%bqsql magic instead. "
405+
"See: https://dataframes.bigquery.dev/notebooks/getting_started/magics.html"
402406
),
403407
)
404408
@magic_arguments.argument(
@@ -510,6 +514,13 @@ def _split_args_line(line: str) -> Tuple[str, str]:
510514

511515

512516
def _query_with_bigframes(query: str, params: List[Any], args: Any):
517+
warnings.warn(
518+
"The bigframes engine is deprecated. Please use %load_ext bigframes "
519+
"and the %%bqsql magic instead. "
520+
"See: https://dataframes.bigquery.dev/notebooks/getting_started/magics.html",
521+
FutureWarning,
522+
stacklevel=2,
523+
)
513524
if args.dry_run:
514525
raise ValueError("Dry run is not supported by bigframes engine.")
515526

packages/bigquery-magics/bigquery_magics/config.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
from dataclasses import dataclass
1616
from typing import Optional
17+
import warnings
1718

1819
import google.api_core.client_options as client_options
1920
import google.cloud.bigquery as bigquery
@@ -183,10 +184,15 @@ def project(self, value):
183184

184185
@property
185186
def engine(self) -> str:
186-
"""Engine to run the query. Could either be "pandas" or "bigframes".
187+
"""[Deprecated] Engine to run the query. Could either be "pandas" or
188+
"bigframes".
187189
188190
If using "pandas", the query result will be stored in a Pandas dataframe.
189-
If using "bigframes", the query result will be stored in a bigframes dataframe instead.
191+
If using "bigframes", the query result will be stored in a bigframes
192+
dataframe instead.
193+
194+
Please use ``%load_ext bigframes`` and the ``%%bqsql`` magic instead.
195+
See: https://dataframes.bigquery.dev/notebooks/getting_started/magics.html
190196
191197
Example:
192198
Manully setting the content engine:
@@ -200,6 +206,14 @@ def engine(self) -> str:
200206
def engine(self, value):
201207
if value != "pandas" and value != "bigframes":
202208
raise ValueError("engine must be either 'pandas' or 'bigframes'")
209+
if value == "bigframes":
210+
warnings.warn(
211+
"The bigframes engine is deprecated. Please use %load_ext bigframes "
212+
"and the %%bqsql magic instead. "
213+
"See: https://dataframes.bigquery.dev/notebooks/getting_started/magics.html",
214+
FutureWarning,
215+
stacklevel=2,
216+
)
203217
self._engine = value
204218

205219

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# Copyright 2026 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+
import pytest
16+
17+
from bigquery_magics import bigquery as magics
18+
import bigquery_magics.config
19+
20+
21+
@pytest.fixture(autouse=True)
22+
def mock_bq_client_and_credentials(mock_credentials):
23+
from unittest import mock
24+
25+
with mock.patch("google.cloud.bigquery.Client", autospec=True):
26+
with mock.patch("bigquery_magics.core.create_bq_client", autospec=True):
27+
yield
28+
29+
30+
def test_config_engine_setter_warning():
31+
context = bigquery_magics.config.Context()
32+
with pytest.warns(FutureWarning, match="The bigframes engine is deprecated"):
33+
context.engine = "bigframes"
34+
35+
36+
def test_query_with_bigframes_warning(mock_ipython):
37+
# Mocking bigframes.pandas since it might not be installed
38+
from unittest import mock
39+
40+
with mock.patch("bigquery_magics.bigquery.bpd") as mock_bpd:
41+
mock_bpd.read_gbq_query.return_value = mock.MagicMock()
42+
43+
args = mock.MagicMock()
44+
args.engine = "bigframes"
45+
args.dry_run = False
46+
args.max_results = None
47+
args.destination_var = None
48+
args.destination_table = None
49+
50+
with pytest.warns(FutureWarning, match="The bigframes engine is deprecated"):
51+
magics._query_with_bigframes("SELECT 1", [], args)
52+
53+
54+
def test_cell_magic_engine_bigframes_warning(mock_ipython):
55+
from unittest import mock
56+
57+
from IPython.testing.globalipapp import get_ipython
58+
59+
ip = get_ipython()
60+
if ip is None:
61+
from IPython.testing.globalipapp import start_ipython
62+
63+
ip = start_ipython()
64+
65+
ip.extension_manager.load_extension("bigquery_magics")
66+
67+
# Mock the actual execution to avoid needing real credentials/data
68+
with mock.patch("bigquery_magics.bigquery.bpd") as mock_bpd:
69+
mock_bpd.read_gbq_query.return_value = mock.MagicMock()
70+
with pytest.warns(FutureWarning, match="The bigframes engine is deprecated"):
71+
ip.run_cell_magic("bigquery", "--engine bigframes", "SELECT 1")
72+
73+
74+
@pytest.fixture
75+
def mock_ipython():
76+
from unittest import mock
77+
78+
with mock.patch("bigquery_magics.bigquery.get_ipython") as mock_get_ipython:
79+
yield mock_get_ipython

0 commit comments

Comments
 (0)