Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 823c0ce

Browse files
authoredJul 25, 2024
feat: Add config option to set partial ordering mode (#855)
1 parent eb0ef75 commit 823c0ce

File tree

3 files changed

+37
-14
lines changed

3 files changed

+37
-14
lines changed
 

‎bigframes/_config/bigquery_options.py

+26-7
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616

1717
from __future__ import annotations
1818

19-
from typing import Optional
19+
from enum import Enum
20+
from typing import Literal, Optional
2021
import warnings
2122

2223
import google.api_core.exceptions
@@ -26,6 +27,12 @@
2627
import bigframes.constants
2728
import bigframes.exceptions
2829

30+
31+
class OrderingMode(Enum):
32+
STRICT = "strict"
33+
PARTIAL = "partial"
34+
35+
2936
SESSION_STARTED_MESSAGE = (
3037
"Cannot change '{attribute}' once a session has started. "
3138
"Call bigframes.pandas.close_session() first, if you are using the bigframes.pandas API."
@@ -57,6 +64,14 @@ def _validate_location(value: Optional[str]):
5764
)
5865

5966

67+
def _validate_ordering_mode(value: str) -> OrderingMode:
68+
if value.casefold() == OrderingMode.STRICT.value.casefold():
69+
return OrderingMode.STRICT
70+
if value.casefold() == OrderingMode.PARTIAL.value.casefold():
71+
return OrderingMode.PARTIAL
72+
raise ValueError("Ordering mode must be one of 'strict' or 'partial'.")
73+
74+
6075
class BigQueryOptions:
6176
"""Encapsulates configuration for working with a session."""
6277

@@ -71,7 +86,7 @@ def __init__(
7186
kms_key_name: Optional[str] = None,
7287
skip_bq_connection_check: bool = False,
7388
*,
74-
_strictly_ordered: bool = True,
89+
ordering_mode: Literal["strict", "partial"] = "strict",
7590
):
7691
self._credentials = credentials
7792
self._project = project
@@ -82,8 +97,8 @@ def __init__(
8297
self._kms_key_name = kms_key_name
8398
self._skip_bq_connection_check = skip_bq_connection_check
8499
self._session_started = False
85-
# Determines the ordering strictness for the session. For internal use only.
86-
self._strictly_ordered_internal = _strictly_ordered
100+
# Determines the ordering strictness for the session.
101+
self._ordering_mode = _validate_ordering_mode(ordering_mode)
87102

88103
@property
89104
def application_name(self) -> Optional[str]:
@@ -241,6 +256,10 @@ def kms_key_name(self, value: str):
241256
self._kms_key_name = value
242257

243258
@property
244-
def _strictly_ordered(self) -> bool:
245-
"""Internal use only. Controls whether total row order is always maintained for DataFrame/Series."""
246-
return self._strictly_ordered_internal
259+
def ordering_mode(self) -> Literal["strict", "partial"]:
260+
"""Controls whether total row order is always maintained for DataFrame/Series."""
261+
return self._ordering_mode.value
262+
263+
@ordering_mode.setter
264+
def ordering_mode(self, ordering_mode: Literal["strict", "partial"]) -> None:
265+
self._ordering_mode = _validate_ordering_mode(ordering_mode)

‎bigframes/session/__init__.py

+9-3
Original file line numberDiff line numberDiff line change
@@ -297,15 +297,21 @@ def __init__(
297297
self._execution_count = 0
298298
# Whether this session treats objects as totally ordered.
299299
# Will expose as feature later, only False for internal testing
300-
self._strictly_ordered: bool = context._strictly_ordered
300+
self._strictly_ordered: bool = context.ordering_mode != "partial"
301+
if not self._strictly_ordered:
302+
warnings.warn(
303+
"Partial ordering mode is a preview feature and is subject to change.",
304+
bigframes.exceptions.PreviewWarning,
305+
)
306+
301307
# Sequential index needs total ordering to generate, so use null index with unstrict ordering.
302308
self._default_index_type: bigframes.enums.DefaultIndexKind = (
303309
bigframes.enums.DefaultIndexKind.SEQUENTIAL_INT64
304-
if context._strictly_ordered
310+
if self._strictly_ordered
305311
else bigframes.enums.DefaultIndexKind.NULL
306312
)
307313
self._compiler = bigframes.core.compile.SQLCompiler(
308-
strict=context._strictly_ordered
314+
strict=self._strictly_ordered
309315
)
310316

311317
self._remote_function_session = bigframes_rf._RemoteFunctionSession()

‎tests/system/conftest.py

+2-4
Original file line numberDiff line numberDiff line change
@@ -141,17 +141,15 @@ def session() -> Generator[bigframes.Session, None, None]:
141141

142142
@pytest.fixture(scope="session", params=["ordered", "unordered"])
143143
def maybe_ordered_session(request) -> Generator[bigframes.Session, None, None]:
144-
context = bigframes.BigQueryOptions(
145-
location="US", _strictly_ordered=request.param == "ordered"
146-
)
144+
context = bigframes.BigQueryOptions(location="US", ordering_mode="partial")
147145
session = bigframes.Session(context=context)
148146
yield session
149147
session.close() # close generated session at cleanup type
150148

151149

152150
@pytest.fixture(scope="session")
153151
def unordered_session() -> Generator[bigframes.Session, None, None]:
154-
context = bigframes.BigQueryOptions(location="US", _strictly_ordered=False)
152+
context = bigframes.BigQueryOptions(location="US", ordering_mode="partial")
155153
session = bigframes.Session(context=context)
156154
yield session
157155
session.close() # close generated session at cleanup type

0 commit comments

Comments
 (0)
Failed to load comments.