Skip to content

Commit 3c64483

Browse files
author
Chris Rossi
authored
fix: properly handle explicitly passing default namespace (googleapis#488)
Fixes googleapis#476.
1 parent cc6d561 commit 3c64483

File tree

4 files changed

+52
-1
lines changed

4 files changed

+52
-1
lines changed

google/cloud/ndb/query.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1281,7 +1281,7 @@ def __init__(self, config=None, context=None, **kwargs):
12811281
if not self.project:
12821282
self.project = context.client.project
12831283

1284-
if not self.namespace:
1284+
if self.namespace is None:
12851285
self.namespace = context.get_namespace()
12861286

12871287

tests/system/conftest.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,18 @@
1616
log = logging.getLogger(__name__)
1717

1818

19+
@pytest.fixture(scope="session", autouse=True)
20+
def preclean():
21+
"""Clean out default namespace in test database."""
22+
ds_client = _make_ds_client(None)
23+
for kind in (KIND, OTHER_KIND):
24+
query = ds_client.query(kind=kind)
25+
query.keys_only()
26+
for page in query.fetch().pages:
27+
keys = [entity.key for entity in page]
28+
ds_client.delete_multi(keys)
29+
30+
1931
def _make_ds_client(namespace):
2032
emulator = bool(os.environ.get("DATASTORE_EMULATOR_HOST"))
2133
if emulator:

tests/system/test_query.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,39 @@ class SomeKind(ndb.Model):
315315
assert results[0].key.namespace() == other_namespace
316316

317317

318+
def test_query_default_namespace_when_context_namespace_is_other(
319+
client_context, dispose_of, other_namespace
320+
):
321+
"""Regression test for #476.
322+
323+
https://github.com/googleapis/python-ndb/issues/476
324+
"""
325+
326+
class SomeKind(ndb.Model):
327+
foo = ndb.IntegerProperty()
328+
bar = ndb.StringProperty()
329+
330+
entity1 = SomeKind(foo=1, bar="a", id="x", namespace=other_namespace)
331+
entity1.put()
332+
dispose_of(entity1.key._key)
333+
334+
entity2 = SomeKind(foo=2, bar="b", id="x", namespace="")
335+
entity2.put()
336+
dispose_of(entity2.key._key)
337+
338+
eventually(
339+
SomeKind.query(namespace=other_namespace).fetch, length_equals(1)
340+
)
341+
342+
with client_context.new(namespace=other_namespace).use():
343+
query = SomeKind.query(namespace="")
344+
results = eventually(query.fetch, length_equals(1))
345+
346+
assert results[0].foo == 2
347+
assert results[0].bar == "b"
348+
assert results[0].key.namespace() is None
349+
350+
318351
@pytest.mark.usefixtures("client_context")
319352
def test_filter_equal(ds_entity):
320353
for i in range(5):

tests/unit/test_query.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,12 @@ def test_copy():
8989
assert options.project == "app2"
9090
assert options.namespace == "foo"
9191

92+
@staticmethod
93+
def test_explicitly_set_default_namespace(in_context):
94+
with in_context.new(namespace="somethingelse").use() as context:
95+
options = query_module.QueryOptions(context=context, namespace="")
96+
assert options.namespace == ""
97+
9298

9399
class TestPropertyOrder:
94100
@staticmethod

0 commit comments

Comments
 (0)