Skip to content

Commit f74f417

Browse files
committed
fix - support ordering by key for multi queries
1 parent 3d8ecdf commit f74f417

File tree

2 files changed

+60
-5
lines changed

2 files changed

+60
-5
lines changed

google/cloud/ndb/_datastore_query.py

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
from google.cloud.datastore_v1.proto import datastore_pb2
2626
from google.cloud.datastore_v1.proto import entity_pb2
2727
from google.cloud.datastore_v1.proto import query_pb2
28-
from google.cloud.datastore import helpers
28+
from google.cloud.datastore import helpers, Key
2929

3030
from google.cloud.ndb import context as context_module
3131
from google.cloud.ndb import _datastore_api
@@ -801,10 +801,22 @@ def _compare(self, other):
801801
return NotImplemented
802802

803803
for order in self.order_by:
804-
this_value_pb = self.result_pb.entity.properties[order.name]
805-
this_value = helpers._get_value_from_value_pb(this_value_pb)
806-
other_value_pb = other.result_pb.entity.properties[order.name]
807-
other_value = helpers._get_value_from_value_pb(other_value_pb)
804+
805+
if order.name == '__key__':
806+
this_value = helpers.key_from_protobuf(self.result_pb.entity.key)
807+
other_value = helpers.key_from_protobuf(other.result_pb.entity.key)
808+
else:
809+
this_value_pb = self.result_pb.entity.properties[order.name]
810+
this_value = helpers._get_value_from_value_pb(this_value_pb)
811+
other_value_pb = other.result_pb.entity.properties[order.name]
812+
other_value = helpers._get_value_from_value_pb(other_value_pb)
813+
814+
# Compare key paths if ordering by key
815+
if isinstance(this_value, Key):
816+
this_value = this_value.flat_path
817+
818+
if isinstance(other_value, Key):
819+
other_value = other_value.flat_path
808820

809821
direction = -1 if order.reverse else 1
810822

tests/system/test_query.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -750,6 +750,49 @@ class SomeKind(ndb.Model):
750750
results[0].foo
751751

752752

753+
@pytest.mark.usefixtures("client_context")
754+
def test_multiquery_with_order_by_key(ds_entity):
755+
"""Verify multiqueries work when ordering by key"""
756+
757+
for i in range(5):
758+
entity_id = test_utils.system.unique_resource_id()
759+
ds_entity(KIND, entity_id, foo=i)
760+
761+
class SomeKind(ndb.Model):
762+
foo = ndb.IntegerProperty()
763+
764+
query = (
765+
SomeKind.query()
766+
.order(SomeKind.key)
767+
.filter(ndb.OR(SomeKind.foo == 4, SomeKind.foo == 3, SomeKind.foo == 1))
768+
)
769+
770+
results = eventually(query.fetch, length_equals(3))
771+
assert [entity.foo for entity in results] == [1, 3, 4]
772+
773+
@pytest.mark.usefixtures("client_context")
774+
def test_multiquery_with_order_value_by_key(ds_entity, client_context):
775+
"""Check ordering by key values an Entity references"""
776+
project = client_context.client.project
777+
namespace = client_context.get_namespace()
778+
779+
for i in range(5):
780+
entity_id = test_utils.system.unique_resource_id()
781+
ds_entity(KIND, entity_id, foo=i, bar=ds_key_module.Key("test_key", i + 1, project=project, namespace=namespace))
782+
783+
class SomeKind(ndb.Model):
784+
foo = ndb.IntegerProperty()
785+
bar = ndb.KeyProperty()
786+
787+
query = (
788+
SomeKind.query()
789+
.order(SomeKind.bar)
790+
.filter(ndb.OR(SomeKind.foo == 4, SomeKind.foo == 3, SomeKind.foo == 1))
791+
)
792+
793+
results = eventually(query.fetch, length_equals(3))
794+
assert [entity.foo for entity in results] == [1, 3, 4]
795+
753796
@pytest.mark.usefixtures("client_context")
754797
def test_count_with_multi_query(ds_entity):
755798
for i in range(5):

0 commit comments

Comments
 (0)