Skip to content
This repository was archived by the owner on Mar 6, 2026. It is now read-only.

Commit f491fd1

Browse files
chmoderChris Rossi
authored andcommitted
Allow class member values in projection and distinct queries (#214)
Cloud datastore needs projection and distinct properties to be strings. This commit sets the converted properties so they may be used by the rest of the query. (Fixes #212)
1 parent ac3b7be commit f491fd1

2 files changed

Lines changed: 42 additions & 2 deletions

File tree

google/cloud/ndb/query.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1406,7 +1406,8 @@ def __init__(
14061406
"projection must be a tuple, list or None; "
14071407
"received {}".format(projection)
14081408
)
1409-
self._check_properties(self._to_property_names(projection))
1409+
projection = self._to_property_names(projection)
1410+
self._check_properties(projection)
14101411
self.projection = tuple(projection)
14111412

14121413
if distinct_on is not None and group_by is not None:
@@ -1426,7 +1427,8 @@ def __init__(
14261427
"distinct_on must be a tuple, list or None; "
14271428
"received {}".format(distinct_on)
14281429
)
1429-
self._check_properties(self._to_property_names(distinct_on))
1430+
distinct_on = self._to_property_names(distinct_on)
1431+
self._check_properties(distinct_on)
14301432
self.distinct_on = tuple(distinct_on)
14311433

14321434
def __repr__(self):

tests/unit/test_query.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1165,6 +1165,44 @@ def test_constructor_with_ancestor_parameterized_thing():
11651165
query = query_module.Query(ancestor=query_module.ParameterizedThing())
11661166
assert isinstance(query.ancestor, query_module.ParameterizedThing)
11671167

1168+
@staticmethod
1169+
@pytest.mark.usefixtures("in_context")
1170+
@unittest.mock.patch("google.cloud.ndb.query._datastore_query")
1171+
def test_constructor_with_class_attribute_projection(_datastore_query):
1172+
class Foo(model.Model):
1173+
string_attr = model.StringProperty()
1174+
1175+
class Bar(model.Model):
1176+
bar_attr = model.StructuredProperty(Foo)
1177+
1178+
query = Bar.query(projection=[Bar.bar_attr.string_attr])
1179+
1180+
assert query.projection[0] == ("bar_attr.string_attr",)[0]
1181+
1182+
query.fetch()
1183+
1184+
@staticmethod
1185+
@pytest.mark.usefixtures("in_context")
1186+
@unittest.mock.patch("google.cloud.ndb.query._datastore_query")
1187+
def test_constructor_with_class_attribute_projection_and_distinct(
1188+
_datastore_query
1189+
):
1190+
class Foo(model.Model):
1191+
string_attr = model.StringProperty()
1192+
1193+
class Bar(model.Model):
1194+
bar_attr = model.StructuredProperty(Foo)
1195+
1196+
query = Bar.query(
1197+
projection=[Bar.bar_attr.string_attr],
1198+
distinct_on=[Bar.bar_attr.string_attr],
1199+
)
1200+
1201+
assert query.projection[0] == ("bar_attr.string_attr",)[0]
1202+
assert query.distinct_on[0] == ("bar_attr.string_attr",)[0]
1203+
1204+
query.fetch()
1205+
11681206
@staticmethod
11691207
@pytest.mark.usefixtures("in_context")
11701208
def test_constructor_with_projection():

0 commit comments

Comments
 (0)