From f491fd13331be1993259d2d5cdf62a76cfcdd146 Mon Sep 17 00:00:00 2001 From: Thomas Cross Date: Tue, 1 Oct 2019 15:22:34 -0500 Subject: [PATCH] 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) --- google/cloud/ndb/query.py | 6 ++++-- tests/unit/test_query.py | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/google/cloud/ndb/query.py b/google/cloud/ndb/query.py index d4f194b8..0845af62 100644 --- a/google/cloud/ndb/query.py +++ b/google/cloud/ndb/query.py @@ -1406,7 +1406,8 @@ def __init__( "projection must be a tuple, list or None; " "received {}".format(projection) ) - self._check_properties(self._to_property_names(projection)) + projection = self._to_property_names(projection) + self._check_properties(projection) self.projection = tuple(projection) if distinct_on is not None and group_by is not None: @@ -1426,7 +1427,8 @@ def __init__( "distinct_on must be a tuple, list or None; " "received {}".format(distinct_on) ) - self._check_properties(self._to_property_names(distinct_on)) + distinct_on = self._to_property_names(distinct_on) + self._check_properties(distinct_on) self.distinct_on = tuple(distinct_on) def __repr__(self): diff --git a/tests/unit/test_query.py b/tests/unit/test_query.py index b87b22f6..e8e68bbf 100644 --- a/tests/unit/test_query.py +++ b/tests/unit/test_query.py @@ -1165,6 +1165,44 @@ def test_constructor_with_ancestor_parameterized_thing(): query = query_module.Query(ancestor=query_module.ParameterizedThing()) assert isinstance(query.ancestor, query_module.ParameterizedThing) + @staticmethod + @pytest.mark.usefixtures("in_context") + @unittest.mock.patch("google.cloud.ndb.query._datastore_query") + def test_constructor_with_class_attribute_projection(_datastore_query): + class Foo(model.Model): + string_attr = model.StringProperty() + + class Bar(model.Model): + bar_attr = model.StructuredProperty(Foo) + + query = Bar.query(projection=[Bar.bar_attr.string_attr]) + + assert query.projection[0] == ("bar_attr.string_attr",)[0] + + query.fetch() + + @staticmethod + @pytest.mark.usefixtures("in_context") + @unittest.mock.patch("google.cloud.ndb.query._datastore_query") + def test_constructor_with_class_attribute_projection_and_distinct( + _datastore_query + ): + class Foo(model.Model): + string_attr = model.StringProperty() + + class Bar(model.Model): + bar_attr = model.StructuredProperty(Foo) + + query = Bar.query( + projection=[Bar.bar_attr.string_attr], + distinct_on=[Bar.bar_attr.string_attr], + ) + + assert query.projection[0] == ("bar_attr.string_attr",)[0] + assert query.distinct_on[0] == ("bar_attr.string_attr",)[0] + + query.fetch() + @staticmethod @pytest.mark.usefixtures("in_context") def test_constructor_with_projection():