[go: up one dir, main page]

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Allow queries using server side IN. #954

Merged
merged 2 commits into from Feb 28, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Prev Previous commit
Rename force_server to server_op.
  • Loading branch information
sorced-jim committed Feb 28, 2024
commit b3f43f9961ba64949d169e3ca18d7e0aad0606b4
4 changes: 2 additions & 2 deletions google/cloud/ndb/model.py
Expand Up @@ -1258,7 +1258,7 @@ def __ge__(self, value):
"""FilterNode: Represents the ``>=`` comparison."""
return self._comparison(">=", value)

def _IN(self, value, force_server=False):
def _IN(self, value, server_op=False):
"""For the ``in`` comparison operator.

The ``in`` operator cannot be overloaded in the way we want
Expand Down Expand Up @@ -1315,7 +1315,7 @@ def _IN(self, value, force_server=False):
sub_value = self._datastore_type(sub_value)
values.append(sub_value)

return query.FilterNode(self._name, "in", values, force_server=force_server)
return query.FilterNode(self._name, "in", values, server_op=server_op)

IN = _IN
"""Used to check if a property value is contained in a set of values.
Expand Down
6 changes: 3 additions & 3 deletions google/cloud/ndb/query.py
Expand Up @@ -619,7 +619,7 @@ class FilterNode(Node):
opsymbol (str): The comparison operator. One of ``=``, ``!=``, ``<``,
``<=``, ``>``, ``>=`` or ``in``.
value (Any): The value to filter on / relative to.
force_server (bool): Force the operator to use a server side filter.
server_op (bool): Force the operator to use a server side filter.

Raises:
TypeError: If ``opsymbol`` is ``"in"`` but ``value`` is not a
Expand All @@ -631,7 +631,7 @@ class FilterNode(Node):
_opsymbol = None
_value = None

def __new__(cls, name, opsymbol, value, force_server=False):
def __new__(cls, name, opsymbol, value, server_op=False):
# Avoid circular import in Python 2.7
from google.cloud.ndb import model

Expand All @@ -649,7 +649,7 @@ def __new__(cls, name, opsymbol, value, force_server=False):
return FalseNode()
if len(nodes) == 1:
return nodes[0]
if not force_server:
if not server_op:
return DisjunctionNode(*nodes)

instance = super(FilterNode, cls).__new__(cls)
Expand Down
4 changes: 1 addition & 3 deletions tests/system/test_query.py
Expand Up @@ -882,9 +882,7 @@ def make_entities():
for key in make_entities():
dispose_of(key._key)

query = SomeKind.query().filter(
SomeKind.foo.IN([1, 2, n_entities], force_server=True)
)
query = SomeKind.query().filter(SomeKind.foo.IN([1, 2, n_entities], server_op=True))
eventually(query.fetch, length_equals(n_entities))

results, cursor, more = query.fetch_page(page_size)
Expand Down
21 changes: 17 additions & 4 deletions tests/unit/test_model.py
Expand Up @@ -549,7 +549,7 @@ def test__IN_wrong_container():
assert model.Property._FIND_METHODS_CACHE == {}

@staticmethod
def test__IN():
def test__IN_default():
prop = model.Property("name", indexed=True)
or_node = prop._IN(["a", None, "xy"])
expected = query_module.DisjunctionNode(
Expand All @@ -561,18 +561,31 @@ def test__IN():
# Also verify the alias
assert or_node == prop.IN(["a", None, "xy"])

@staticmethod
sorced-jim marked this conversation as resolved.
Show resolved Hide resolved
def test__IN_client():
prop = model.Property("name", indexed=True)
or_node = prop._IN(["a", None, "xy"], server_op=False)
expected = query_module.DisjunctionNode(
query_module.FilterNode("name", "=", "a"),
query_module.FilterNode("name", "=", None),
query_module.FilterNode("name", "=", "xy"),
)
assert or_node == expected
# Also verify the alias
assert or_node == prop.IN(["a", None, "xy"])

@staticmethod
def test_server__IN():
prop = model.Property("name", indexed=True)
in_node = prop._IN(["a", None, "xy"], force_server=True)
assert in_node == prop.IN(["a", None, "xy"], force_server=True)
in_node = prop._IN(["a", None, "xy"], server_op=True)
assert in_node == prop.IN(["a", None, "xy"], server_op=True)
assert in_node != query_module.DisjunctionNode(
query_module.FilterNode("name", "=", "a"),
query_module.FilterNode("name", "=", None),
query_module.FilterNode("name", "=", "xy"),
)
assert in_node == query_module.FilterNode(
"name", "in", ["a", None, "xy"], force_server=True
"name", "in", ["a", None, "xy"], server_op=True
)

@staticmethod
Expand Down