Skip to content

Commit c24085f

Browse files
authored
Rename group_by to distinct_on, for consistency with datastore (#53)
* rename group_by to distinct_on, for consistency with datastore.
1 parent 3049373 commit c24085f

File tree

4 files changed

+48
-26
lines changed

4 files changed

+48
-26
lines changed

packages/google-cloud-ndb/src/google/cloud/ndb/_datastore_query.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,10 @@ def _query_to_protobuf(query):
119119
for name in query.projection
120120
]
121121

122-
if query.group_by:
122+
if query.distinct_on:
123123
query_args["distinct_on"] = [
124-
query_pb2.PropertyReference(name=name) for name in query.group_by
124+
query_pb2.PropertyReference(name=name)
125+
for name in query.distinct_on
125126
]
126127

127128
filters = []

packages/google-cloud-ndb/src/google/cloud/ndb/query.py

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -948,17 +948,19 @@ class Query:
948948
filters (Union[Node, tuple]): Node representing a filter expression
949949
tree. Property filters applied by this query. The sequence
950950
is ``(property_name, operator, value)``.
951-
order_by (Union[tuple, list]): The field names used to
951+
order_by (Union[list, tuple]): The field names used to
952952
order query results. Renamed `order` in google.cloud.datastore.
953+
orders (Union[list, tuple]): Deprecated. Synonym for order_by.
953954
app (str): The app to restrict results. If not passed, uses the
954955
client's value. Renamed `project` in google.cloud.datastore.
955956
namespace (str): The namespace to which to restrict results.
956957
If not passed, uses the client's value.
957958
default_options (QueryOptions): QueryOptions object.
958959
projection (Union[list, tuple]): The fields returned as part of the
959960
query results.
960-
group_by (Union[list, tuple]): The field names used to group query
961+
distinct_on (Union[list, tuple]): The field names used to group query
961962
results. Renamed distinct_on in google.cloud.datastore.
963+
group_by (Union[list, tuple]): Deprecated. Synonym for distinct_on.
962964
963965
Raises: TypeError if any of the arguments are invalid.
964966
"""
@@ -974,6 +976,7 @@ def __init__(
974976
namespace=None,
975977
default_options=None,
976978
projection=None,
979+
distinct_on=None,
977980
group_by=None,
978981
):
979982
if ancestor is not None:
@@ -1054,17 +1057,24 @@ def __init__(
10541057
self._check_properties(self._to_property_names(projection))
10551058
self.projection = tuple(projection)
10561059

1057-
self.group_by = None
1058-
if group_by is not None:
1059-
if not group_by:
1060-
raise TypeError("group_by argument cannot be empty")
1061-
if not isinstance(group_by, (tuple, list)):
1060+
if distinct_on is not None and group_by is not None:
1061+
raise TypeError(
1062+
"Cannot use both group_by and distinct_on, they are synonyms"
1063+
"(group_by is deprecated now)"
1064+
)
1065+
if distinct_on is None:
1066+
distinct_on = group_by
1067+
self.distinct_on = None
1068+
if distinct_on is not None:
1069+
if not distinct_on:
1070+
raise TypeError("distinct_on argument cannot be empty")
1071+
if not isinstance(distinct_on, (tuple, list)):
10621072
raise TypeError(
1063-
"group_by must be a tuple, list or None; "
1064-
"received {}".format(group_by)
1073+
"distinct_on must be a tuple, list or None; "
1074+
"received {}".format(distinct_on)
10651075
)
1066-
self._check_properties(self._to_property_names(group_by))
1067-
self.group_by = tuple(group_by)
1076+
self._check_properties(self._to_property_names(distinct_on))
1077+
self.distinct_on = tuple(distinct_on)
10681078

10691079
def __repr__(self):
10701080
args = []
@@ -1084,9 +1094,9 @@ def __repr__(self):
10841094
args.append(
10851095
"projection=%r" % (self._to_property_names(self.projection))
10861096
)
1087-
if self.group_by:
1097+
if self.distinct_on:
10881098
args.append(
1089-
"group_by=%r" % (self._to_property_names(self.group_by))
1099+
"distinct_on=%r" % (self._to_property_names(self.distinct_on))
10901100
)
10911101
if self.default_options is not None:
10921102
args.append("default_options=%r" % self.default_options)
@@ -1097,11 +1107,11 @@ def is_distinct(self):
10971107
"""True if results are guaranteed to contain a unique set of property
10981108
values.
10991109
1100-
This happens when every property in the group_by is also in the projection.
1110+
This happens when every property in distinct_on is also in projection.
11011111
"""
11021112
return bool(
1103-
self.group_by
1104-
and set(self._to_property_names(self.group_by))
1113+
self.distinct_on
1114+
and set(self._to_property_names(self.distinct_on))
11051115
<= set(self._to_property_names(self.projection))
11061116
)
11071117

@@ -1141,7 +1151,7 @@ def filter(self, *filters):
11411151
namespace=self.namespace,
11421152
default_options=self.default_options,
11431153
projection=self.projection,
1144-
group_by=self.group_by,
1154+
distinct_on=self.distinct_on,
11451155
)
11461156

11471157
def order(self, *names):
@@ -1170,7 +1180,7 @@ def order(self, *names):
11701180
namespace=self.namespace,
11711181
default_options=self.default_options,
11721182
projection=self.projection,
1173-
group_by=self.group_by,
1183+
distinct_on=self.distinct_on,
11741184
)
11751185

11761186
def analyze(self):
@@ -1248,7 +1258,7 @@ def bind(self, *positional, **keyword):
12481258
namespace=self.namespace,
12491259
default_options=self.default_options,
12501260
projection=self.projection,
1251-
group_by=self.group_by,
1261+
distinct_on=self.distinct_on,
12521262
)
12531263

12541264
def _to_property_names(self, properties):

packages/google-cloud-ndb/tests/system/test_query.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,7 @@ class SomeKind(ndb.Model):
128128
foo = ndb.IntegerProperty()
129129
bar = ndb.StringProperty()
130130

131-
# query = ndb.Query(kind=KIND, distinct_on=("foo",)) # TODO
132-
query = ndb.Query(kind=KIND, group_by=("foo",))
131+
query = ndb.Query(kind=KIND, distinct_on=("foo",))
133132
results = query.fetch()
134133
assert len(results) == 2
135134

packages/google-cloud-ndb/tests/unit/test_query.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,11 +1015,23 @@ class Foo(model.Model):
10151015
assert query.projection == ("x",)
10161016
_check_props.assert_called_once_with(["x"])
10171017

1018+
@staticmethod
1019+
@pytest.mark.usefixtures("in_context")
1020+
def test_constructor_with_distinct_on():
1021+
query = query_module.Query(kind="Foo", distinct_on=["X"])
1022+
assert query.distinct_on == ("X",)
1023+
10181024
@staticmethod
10191025
@pytest.mark.usefixtures("in_context")
10201026
def test_constructor_with_group_by():
10211027
query = query_module.Query(kind="Foo", group_by=["X"])
1022-
assert query.group_by == ("X",)
1028+
assert query.distinct_on == ("X",)
1029+
1030+
@staticmethod
1031+
@pytest.mark.usefixtures("in_context")
1032+
def test_constructor_with_distinct_on_and_group_by():
1033+
with pytest.raises(TypeError):
1034+
query_module.Query(distinct_on=[], group_by=[])
10231035

10241036
@staticmethod
10251037
@pytest.mark.usefixtures("in_context")
@@ -1043,7 +1055,7 @@ def test_constructor_with_orders():
10431055

10441056
@staticmethod
10451057
@pytest.mark.usefixtures("in_context")
1046-
def test_constructor_with_orders_and_irder_by():
1058+
def test_constructor_with_orders_and_order_by():
10471059
with pytest.raises(TypeError):
10481060
query_module.Query(orders=[], order_by=[])
10491061

@@ -1120,7 +1132,7 @@ def test___repr__():
11201132
"Query(app='app', namespace='space', kind='Foo', ancestor="
11211133
"Key('a', 'b', app='app', namespace='space'), filters="
11221134
"FilterNode('f', None, None), order_by=[], projection=['x'], "
1123-
"group_by=['X'], default_options=QueryOptions(kind='Bar'))"
1135+
"distinct_on=['X'], default_options=QueryOptions(kind='Bar'))"
11241136
)
11251137
assert query.__repr__() == rep
11261138

0 commit comments

Comments
 (0)