Skip to content

Commit 435c602

Browse files
committed
add system tests and fix pandas warning
1 parent 78d29f0 commit 435c602

File tree

3 files changed

+114
-33
lines changed

3 files changed

+114
-33
lines changed

bigframes/dataframe.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4419,7 +4419,7 @@ def to_dict(
44194419
allow_large_results: Optional[bool] = None,
44204420
**kwargs,
44214421
) -> dict | list[dict]:
4422-
return self.to_pandas(allow_large_results=allow_large_results).to_dict(orient, into, **kwargs) # type: ignore
4422+
return self.to_pandas(allow_large_results=allow_large_results).to_dict(orient=orient, into=into, **kwargs) # type: ignore
44234423

44244424
def to_excel(
44254425
self,
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
# Copyright 2025 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 datetime
16+
17+
import pytest
18+
19+
import bigframes
20+
import bigframes.core.nodes as nodes
21+
22+
23+
def test_read_gbq_query_w_allow_large_results(session: bigframes.Session):
24+
if not hasattr(session.bqclient, "default_job_creation_mode"):
25+
pytest.skip("Jobless query only available on newer google-cloud-bigquery.")
26+
27+
query = "SELECT 1"
28+
29+
# Make sure we don't get a cached table.
30+
configuration = {"query": {"useQueryCache": False}}
31+
32+
# Very small results should wrap a local node.
33+
df_false = session.read_gbq(
34+
query,
35+
configuration=configuration,
36+
allow_large_results=False,
37+
)
38+
assert df_false.shape == (1, 1)
39+
roots_false = df_false._get_block().expr.node.roots
40+
assert any(isinstance(node, nodes.ReadLocalNode) for node in roots_false)
41+
assert not any(isinstance(node, nodes.ReadTableNode) for node in roots_false)
42+
43+
# Large results allowed should wrap a table.
44+
df_true = session.read_gbq(
45+
query,
46+
configuration=configuration,
47+
allow_large_results=True,
48+
)
49+
assert df_true.shape == (1, 1)
50+
roots_true = df_true._get_block().expr.node.roots
51+
assert any(isinstance(node, nodes.ReadTableNode) for node in roots_true)
52+
53+
54+
def test_read_gbq_query_w_columns(session: bigframes.Session):
55+
query = """
56+
SELECT 1 as int_col,
57+
'a' as str_col,
58+
TIMESTAMP('2025-08-21 10:41:32.123456') as timestamp_col
59+
"""
60+
61+
result = session.read_gbq(
62+
query,
63+
columns=["timestamp_col", "int_col"],
64+
)
65+
assert list(result.columns) == ["timestamp_col", "int_col"]
66+
assert result.to_dict(orient="records") == [
67+
{
68+
"timestamp_col": datetime.datetime(
69+
2025, 8, 21, 10, 41, 32, 123456, tzinfo=datetime.timezone.utc
70+
),
71+
"int_col": 1,
72+
}
73+
]
74+
75+
76+
@pytest.mark.parametrize(
77+
("index_col", "expected_index_names"),
78+
(
79+
pytest.param(
80+
"my_custom_index",
81+
("my_custom_index",),
82+
id="string",
83+
),
84+
pytest.param(
85+
("my_custom_index",),
86+
("my_custom_index",),
87+
id="iterable",
88+
),
89+
pytest.param(
90+
("my_custom_index", "int_col"),
91+
("my_custom_index", "int_col"),
92+
id="multiindex",
93+
),
94+
),
95+
)
96+
def test_read_gbq_query_w_index_col(
97+
session: bigframes.Session, index_col, expected_index_names
98+
):
99+
query = """
100+
SELECT 1 as int_col,
101+
'a' as str_col,
102+
0 as my_custom_index,
103+
TIMESTAMP('2025-08-21 10:41:32.123456') as timestamp_col
104+
"""
105+
106+
result = session.read_gbq(
107+
query,
108+
index_col=index_col,
109+
)
110+
assert tuple(result.index.names) == expected_index_names
111+
assert frozenset(result.columns) == frozenset(
112+
{"int_col", "str_col", "my_custom_index", "timestamp_col"}
113+
) - frozenset(expected_index_names)

tests/system/small/test_session.py

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
import pytest
3434

3535
import bigframes
36-
import bigframes.core.nodes as nodes
3736
import bigframes.dataframe
3837
import bigframes.dtypes
3938
import bigframes.ml.linear_model
@@ -641,37 +640,6 @@ def test_read_gbq_with_configuration(
641640
assert df.shape == (9, 3)
642641

643642

644-
def test_read_gbq_query_w_allow_large_results(session: bigframes.Session):
645-
if not hasattr(session.bqclient, "default_job_creation_mode"):
646-
pytest.skip("Jobless query only available on newer google-cloud-bigquery.")
647-
648-
query = "SELECT 1"
649-
650-
# Make sure we don't get a cached table.
651-
configuration = {"query": {"useQueryCache": False}}
652-
653-
# Very small results should wrap a local node.
654-
df_false = session.read_gbq(
655-
query,
656-
configuration=configuration,
657-
allow_large_results=False,
658-
)
659-
assert df_false.shape == (1, 1)
660-
roots_false = df_false._get_block().expr.node.roots
661-
assert any(isinstance(node, nodes.ReadLocalNode) for node in roots_false)
662-
assert not any(isinstance(node, nodes.ReadTableNode) for node in roots_false)
663-
664-
# Large results allowed should wrap a table.
665-
df_true = session.read_gbq(
666-
query,
667-
configuration=configuration,
668-
allow_large_results=True,
669-
)
670-
assert df_true.shape == (1, 1)
671-
roots_true = df_true._get_block().expr.node.roots
672-
assert any(isinstance(node, nodes.ReadTableNode) for node in roots_true)
673-
674-
675643
def test_read_gbq_with_custom_global_labels(
676644
session: bigframes.Session, scalars_table_id: str
677645
):

0 commit comments

Comments
 (0)