def test_query_legacy_repeated_structured_property(ds_entity): class OtherKind(ndb.Model): one = ndb.StringProperty() two = ndb.StringProperty() three = ndb.StringProperty() class SomeKind(ndb.Model): foo = ndb.IntegerProperty() bar = ndb.StructuredProperty(OtherKind, repeated=True) entity_id = test_utils.system.unique_resource_id() ds_entity( KIND, entity_id, **{ "foo": 1, "bar.one": [u"pish", u"bish"], "bar.two": [u"posh", u"bosh"], "bar.three": [u"pash", u"bash"], } ) entity_id = test_utils.system.unique_resource_id() ds_entity( KIND, entity_id, **{ "foo": 2, "bar.one": [u"bish", u"pish"], "bar.two": [u"bosh", u"posh"], "bar.three": [u"bass", u"pass"], } ) entity_id = test_utils.system.unique_resource_id() ds_entity( KIND, entity_id, **{ "foo": 3, "bar.one": [u"pish", u"bish"], "bar.two": [u"fosh", u"posh"], "bar.three": [u"fash", u"bash"], } ) eventually(SomeKind.query().fetch, _length_equals(3)) query = ( SomeKind.query() .filter( SomeKind.bar == OtherKind(one=u"pish", two=u"posh"), SomeKind.bar == OtherKind(two=u"posh", three=u"pash"), ) .order(SomeKind.foo) ) results = query.fetch() assert len(results) == 1 assert results[0].foo == 1
def test_map(dispose_of): class SomeKind(ndb.Model): foo = ndb.StringProperty() ref = ndb.KeyProperty() class OtherKind(ndb.Model): foo = ndb.StringProperty() foos = ("aa", "bb", "cc", "dd", "ee") others = [OtherKind(foo=foo) for foo in foos] other_keys = ndb.put_multi(others) for key in other_keys: dispose_of(key._key) things = [SomeKind(foo=foo, ref=key) for foo, key in zip(foos, other_keys)] keys = ndb.put_multi(things) for key in keys: dispose_of(key._key) eventually(SomeKind.query().fetch, _length_equals(5)) eventually(OtherKind.query().fetch, _length_equals(5)) @ndb.tasklet def get_other_foo(thing): other = yield thing.ref.get_async() raise ndb.Return(other.foo) query = SomeKind.query().order(SomeKind.foo) assert query.map(get_other_foo) == foos
def test_offset_and_limit_with_or_filter(dispose_of): class SomeKind(ndb.Model): foo = ndb.IntegerProperty() bar = ndb.StringProperty() @ndb.toplevel def make_entities(): keys = yield ( SomeKind(foo=0, bar="a").put_async(), SomeKind(foo=1, bar="b").put_async(), SomeKind(foo=2, bar="a").put_async(), SomeKind(foo=3, bar="b").put_async(), SomeKind(foo=4, bar="a").put_async(), SomeKind(foo=5, bar="b").put_async(), ) for key in keys: dispose_of(key._key) make_entities() eventually(SomeKind.query().fetch, _length_equals(6)) query = SomeKind.query(ndb.OR(SomeKind.bar == "a", SomeKind.bar == "b")) query = query.order(SomeKind.foo) results = query.fetch(offset=1, limit=2) assert [entity.foo for entity in results] == [1, 2]
def test_fetch_page(dispose_of): page_size = 5 n_entities = page_size * 2 class SomeKind(ndb.Model): foo = ndb.IntegerProperty() @ndb.toplevel def make_entities(): entities = [SomeKind(foo=i) for i in range(n_entities)] keys = yield [entity.put_async() for entity in entities] raise ndb.Return(keys) for key in make_entities(): dispose_of(key._key) query = SomeKind.query().order(SomeKind.foo) eventually(query.fetch, _length_equals(n_entities)) results, cursor, more = query.fetch_page(page_size) assert [entity.foo for entity in results] == [0, 1, 2, 3, 4] assert more safe_cursor = cursor.urlsafe() next_cursor = ndb.Cursor(urlsafe=safe_cursor) results, cursor, more = query.fetch_page(page_size, start_cursor=next_cursor) assert [entity.foo for entity in results] == [5, 6, 7, 8, 9] results, cursor, more = query.fetch_page(page_size, start_cursor=cursor) assert not results assert not more
def test_query_legacy_repeated_structured_property_with_name(ds_entity): class OtherKind(ndb.Model): one = ndb.StringProperty() two = ndb.StringProperty() three = ndb.StringProperty() class SomeKind(ndb.Model): foo = ndb.IntegerProperty() bar = ndb.StructuredProperty(OtherKind, "b", repeated=True) entity_id = test_utils.system.unique_resource_id() ds_entity( KIND, entity_id, **{ "foo": 1, "b.one": [u"pish", u"bish"], "b.two": [u"posh", u"bosh"], "b.three": [u"pash", u"bash"], }) eventually(SomeKind.query().fetch, _length_equals(1)) query = SomeKind.query() results = query.fetch() assert len(results) == 1 assert results[0].bar[0].one == u"pish"
def test_polymodel_query(ds_entity): class Animal(ndb.PolyModel): foo = ndb.IntegerProperty() class Cat(Animal): pass animal = Animal(foo=1) animal.put() cat = Cat(foo=2) cat.put() query = Animal.query() results = eventually(query.fetch, _length_equals(2)) results = sorted(results, key=operator.attrgetter("foo")) assert isinstance(results[0], Animal) assert not isinstance(results[0], Cat) assert isinstance(results[1], Animal) assert isinstance(results[1], Cat) query = Cat.query() results = eventually(query.fetch, _length_equals(1)) assert isinstance(results[0], Animal) assert isinstance(results[0], Cat)
def test_query_repeated_structured_property_with_properties_legacy_data( client_context, dispose_of ): class OtherKind(ndb.Model): one = ndb.StringProperty() two = ndb.StringProperty() three = ndb.StringProperty() class SomeKind(ndb.Model): foo = ndb.IntegerProperty() bar = ndb.StructuredProperty(OtherKind, repeated=True) @ndb.synctasklet def make_entities(): entity1 = SomeKind( foo=1, bar=[ OtherKind(one="pish", two="posh", three="pash"), OtherKind(one="bish", two="bosh", three="bash"), ], ) entity2 = SomeKind( foo=2, bar=[ OtherKind(one="pish", two="bosh", three="bass"), OtherKind(one="bish", two="posh", three="pass"), ], ) entity3 = SomeKind( foo=3, bar=[ OtherKind(one="fish", two="fosh", three="fash"), OtherKind(one="bish", two="bosh", three="bash"), ], ) keys = yield ( entity1.put_async(), entity2.put_async(), entity3.put_async(), ) raise ndb.Return(keys) with client_context.new(legacy_data=True).use(): keys = make_entities() for key in keys: dispose_of(key._key) eventually(SomeKind.query().fetch, _length_equals(3)) query = ( SomeKind.query() .filter(SomeKind.bar.one == "pish", SomeKind.bar.two == "posh") .order(SomeKind.foo) ) results = query.fetch() assert len(results) == 2 assert results[0].foo == 1 assert results[1].foo == 2
def test_fetch_page_with_repeated_structured_property(dispose_of): """Regression test for Issue #254. https://github.com/googleapis/python-ndb/issues/254 """ class OtherKind(ndb.Model): one = ndb.StringProperty() two = ndb.StringProperty() three = ndb.StringProperty() class SomeKind(ndb.Model): foo = ndb.IntegerProperty() bar = ndb.StructuredProperty(OtherKind, repeated=True) @ndb.synctasklet def make_entities(): entity1 = SomeKind( foo=1, bar=[ OtherKind(one="pish", two="posh", three="pash"), OtherKind(one="bish", two="bosh", three="bash"), ], ) entity2 = SomeKind( foo=2, bar=[ OtherKind(one="bish", two="bosh", three="bass"), OtherKind(one="pish", two="posh", three="pass"), ], ) entity3 = SomeKind( foo=3, bar=[ OtherKind(one="pish", two="fosh", three="fash"), OtherKind(one="bish", two="posh", three="bash"), ], ) keys = yield ( entity1.put_async(), entity2.put_async(), entity3.put_async(), ) raise ndb.Return(keys) keys = make_entities() for key in keys: dispose_of(key._key) eventually(SomeKind.query().fetch, _length_equals(3)) query = (SomeKind.query().filter( SomeKind.bar == OtherKind(one="pish", two="posh"), SomeKind.bar == OtherKind(two="posh", three="pash"), ).order(SomeKind.foo)) with pytest.raises(TypeError): query.fetch_page(page_size=10)
def test_count_all(ds_entity): for i in range(5): entity_id = test_utils.system.unique_resource_id() ds_entity(KIND, entity_id, foo=i) class SomeKind(ndb.Model): foo = ndb.IntegerProperty() query = SomeKind.query() eventually(query.count, _equals(5))
def test_query_structured_property_with_projection(dispose_of): class OtherKind(ndb.Model): one = ndb.StringProperty() two = ndb.StringProperty() three = ndb.StringProperty() class SomeKind(ndb.Model): foo = ndb.IntegerProperty() bar = ndb.StructuredProperty(OtherKind) @ndb.synctasklet def make_entities(): entity1 = SomeKind( foo=1, bar=OtherKind(one="pish", two="posh", three="pash") ) entity2 = SomeKind( foo=2, bar=OtherKind(one="bish", two="bosh", three="bush") ) entity3 = SomeKind( foo=3, bar=OtherKind(one="pish", two="moppish", three="pass the peas"), ) keys = yield ( entity1.put_async(), entity2.put_async(), entity3.put_async(), ) raise ndb.Return(keys) keys = make_entities() for key in keys: dispose_of(key._key) eventually(SomeKind.query().fetch, _length_equals(3)) query = ( SomeKind.query(projection=("foo", "bar.one", "bar.two")) .filter(SomeKind.foo < 3) .order(SomeKind.foo) ) results = query.fetch() assert len(results) == 2 assert results[0].foo == 1 assert results[0].bar.one == "pish" assert results[0].bar.two == "posh" assert results[1].foo == 2 assert results[1].bar.one == "bish" assert results[1].bar.two == "bosh" with pytest.raises(ndb.UnprojectedPropertyError): results[0].bar.three with pytest.raises(ndb.UnprojectedPropertyError): results[1].bar.three
def test_query_repeated_structured_property_with_entity_twice(dispose_of): class OtherKind(ndb.Model): one = ndb.StringProperty() two = ndb.StringProperty() three = ndb.StringProperty() class SomeKind(ndb.Model): foo = ndb.IntegerProperty() bar = ndb.StructuredProperty(OtherKind, repeated=True) @ndb.synctasklet def make_entities(): entity1 = SomeKind( foo=1, bar=[ OtherKind(one="pish", two="posh", three="pash"), OtherKind(one="bish", two="bosh", three="bash"), ], ) entity2 = SomeKind( foo=2, bar=[ OtherKind(one="bish", two="bosh", three="bass"), OtherKind(one="pish", two="posh", three="pass"), ], ) entity3 = SomeKind( foo=3, bar=[ OtherKind(one="pish", two="fosh", three="fash"), OtherKind(one="bish", two="posh", three="bash"), ], ) keys = yield ( entity1.put_async(), entity2.put_async(), entity3.put_async(), ) return keys keys = make_entities() eventually(SomeKind.query().fetch, _length_equals(3)) for key in keys: dispose_of(key._key) query = (SomeKind.query().filter( SomeKind.bar == OtherKind(one="pish", two="posh"), SomeKind.bar == OtherKind(two="posh", three="pash"), ).order(SomeKind.foo)) results = query.fetch() assert len(results) == 1 assert results[0].foo == 1
def test_get_none(ds_entity): for i in range(5): entity_id = test_utils.system.unique_resource_id() ds_entity(KIND, entity_id, foo=i) class SomeKind(ndb.Model): foo = ndb.IntegerProperty() query = SomeKind.query().order(SomeKind.foo) eventually(query.fetch, _length_equals(5)) assert query.filter(SomeKind.foo == -1).get() is None
def test_count_with_multi_query(ds_entity): for i in range(5): entity_id = test_utils.system.unique_resource_id() ds_entity(KIND, entity_id, foo=i) class SomeKind(ndb.Model): foo = ndb.IntegerProperty() query = SomeKind.query() eventually(query.count, _equals(5)) assert query.filter(SomeKind.foo != 2).count() == 4
def test_offset_and_limit(ds_entity): for i in range(5): entity_id = test_utils.system.unique_resource_id() ds_entity(KIND, entity_id, foo=i) class SomeKind(ndb.Model): foo = ndb.IntegerProperty() eventually(SomeKind.query().fetch, _length_equals(5)) query = SomeKind.query(order_by=["foo"]) results = query.fetch(offset=2, limit=2) assert [entity.foo for entity in results] == [2, 3]
def test_filter_equal(ds_entity): for i in range(5): entity_id = test_utils.system.unique_resource_id() ds_entity(KIND, entity_id, foo=i) class SomeKind(ndb.Model): foo = ndb.IntegerProperty() eventually(SomeKind.query().fetch, _length_equals(5)) query = SomeKind.query(SomeKind.foo == 2) results = query.fetch() assert results[0].foo == 2
def test_filter_not_equal(ds_entity): for i in range(5): entity_id = test_utils.system.unique_resource_id() ds_entity(KIND, entity_id, foo=i) class SomeKind(ndb.Model): foo = ndb.IntegerProperty() eventually(SomeKind.query().fetch, _length_equals(5)) query = SomeKind.query(SomeKind.foo != 2) results = query.fetch() results = sorted(results, key=operator.attrgetter("foo")) assert [entity.foo for entity in results] == [0, 1, 3, 4]
def test_projection_with_json_property(dispose_of): """Regression test for #378 https://github.com/googleapis/python-ndb/issues/378 """ class SomeKind(ndb.Model): foo = ndb.JsonProperty(indexed=True) key = SomeKind(foo={"hi": "mom!"}).put() dispose_of(key._key) eventually(SomeKind.query().fetch, _length_equals(1)) results = SomeKind.query().fetch(projection=[SomeKind.foo]) assert results[0].foo == {"hi": "mom!"}
def test_query_legacy_structured_property(ds_entity): class OtherKind(ndb.Model): one = ndb.StringProperty() two = ndb.StringProperty() three = ndb.StringProperty() class SomeKind(ndb.Model): foo = ndb.IntegerProperty() bar = ndb.StructuredProperty(OtherKind) entity_id = test_utils.system.unique_resource_id() ds_entity( KIND, entity_id, **{"foo": 1, "bar.one": "pish", "bar.two": "posh", "bar.three": "pash"} ) entity_id = test_utils.system.unique_resource_id() ds_entity( KIND, entity_id, **{"foo": 2, "bar.one": "pish", "bar.two": "posh", "bar.three": "push"} ) entity_id = test_utils.system.unique_resource_id() ds_entity( KIND, entity_id, **{ "foo": 3, "bar.one": "pish", "bar.two": "moppish", "bar.three": "pass the peas", } ) eventually(SomeKind.query().fetch, _length_equals(3)) query = ( SomeKind.query() .filter(SomeKind.bar.one == "pish", SomeKind.bar.two == "posh") .order(SomeKind.foo) ) results = query.fetch() assert len(results) == 2 assert results[0].foo == 1 assert results[1].foo == 2
def test_projection_datetime(ds_entity): """Regression test for Issue #261 https://github.com/googleapis/python-ndb/issues/261 """ entity_id = test_utils.system.unique_resource_id() ds_entity( KIND, entity_id, foo=datetime.datetime(2010, 5, 12, 2, 42, tzinfo=pytz.UTC), ) entity_id = test_utils.system.unique_resource_id() ds_entity( KIND, entity_id, foo=datetime.datetime(2010, 5, 12, 2, 43, tzinfo=pytz.UTC), ) class SomeKind(ndb.Model): foo = ndb.DateTimeProperty() bar = ndb.StringProperty() query = SomeKind.query(projection=("foo", )) results = eventually(query.fetch, _length_equals(2)) results = sorted(results, key=operator.attrgetter("foo")) assert results[0].foo == datetime.datetime(2010, 5, 12, 2, 42) assert results[1].foo == datetime.datetime(2010, 5, 12, 2, 43)
def test_get_namespaces(dispose_of): from google.cloud.ndb.metadata import get_namespaces class AnyKind(ndb.Model): foo = ndb.IntegerProperty() entity1 = AnyKind(foo=1, namespace="CoolNamespace") entity1.put() dispose_of(entity1.key._key) entity2 = AnyKind(foo=2, namespace="MyNamespace") entity2.put() dispose_of(entity2.key._key) entity3 = AnyKind(foo=3, namespace="OtherNamespace") entity3.put() dispose_of(entity3.key._key) names = eventually(get_namespaces, _length_at_least(3)) assert (all(name in names for name in ["CoolNamespace", "MyNamespace", "OtherNamespace"]) != []) names = get_namespaces(start="L") assert (all(name in names for name in ["MyNamespace", "OtherNamspace"]) != []) names = get_namespaces(end="N") assert (all(name in names for name in ["CoolNamespace", "MyNamespace"]) != []) names = get_namespaces(start="D", end="N") assert all(name in names for name in ["MyNamespace"]) != []
def test_get_properties_of_kind_different_namespace(dispose_of, namespace): from google.cloud.ndb.metadata import get_properties_of_kind class AnyKind(ndb.Model): foo = ndb.IntegerProperty() bar = ndb.StringProperty() baz = ndb.IntegerProperty() qux = ndb.StringProperty() entity1 = AnyKind(foo=1, bar="x", baz=3, qux="y", namespace="DiffNamespace") entity1.put() dispose_of(entity1.key._key) properties = eventually(lambda: get_properties_of_kind("AnyKind"), _length_at_least(4)) assert properties == ["bar", "baz", "foo", "qux"] properties = get_properties_of_kind("AnyKind", start="c") assert properties == ["foo", "qux"] properties = get_properties_of_kind("AnyKind", end="e") assert properties == ["bar", "baz"] properties = get_properties_of_kind("AnyKind", start="c", end="p") assert properties == ["foo"]
def test_get_representations_of_kind(dispose_of): from google.cloud.ndb.metadata import get_representations_of_kind class AnyKind(ndb.Model): foo = ndb.IntegerProperty() bar = ndb.StringProperty() baz = ndb.IntegerProperty() qux = ndb.StringProperty() entity1 = AnyKind(foo=1, bar="x", baz=3, qux="y") entity1.put() dispose_of(entity1.key._key) representations = eventually( lambda: get_representations_of_kind("AnyKind"), _length_at_least(4)) assert representations == { "bar": ["STRING"], "baz": ["INT64"], "foo": ["INT64"], "qux": ["STRING"], } representations = get_representations_of_kind("AnyKind", start="c") assert representations == {"foo": ["INT64"], "qux": ["STRING"]} representations = get_representations_of_kind("AnyKind", end="e") assert representations == {"bar": ["STRING"], "baz": ["INT64"]} representations = get_representations_of_kind("AnyKind", start="c", end="p") assert representations == {"foo": ["INT64"]}
def test_order_by_with_or_filter(dispose_of): """ Checking to make sure ordering is preserved when merging different results sets. """ class SomeKind(ndb.Model): foo = ndb.IntegerProperty() bar = ndb.StringProperty() @ndb.toplevel def make_entities(): keys = yield ( SomeKind(foo=0, bar="a").put_async(), SomeKind(foo=1, bar="b").put_async(), SomeKind(foo=2, bar="a").put_async(), SomeKind(foo=3, bar="b").put_async(), ) for key in keys: dispose_of(key._key) make_entities() query = SomeKind.query(ndb.OR(SomeKind.bar == "a", SomeKind.bar == "b")) query = query.order(SomeKind.foo) results = eventually(query.fetch, _length_equals(4)) assert [entity.foo for entity in results] == [0, 1, 2, 3]
def test_insert_entity_with_caching(client_context): class SomeKind(ndb.Model): foo = ndb.IntegerProperty() bar = ndb.StringProperty() client_context.set_cache_policy(None) # Use default entity = SomeKind(foo=42, bar="none") key = entity.put() with client_context.new(cache_policy=False).use(): # Sneaky. Delete entity out from under cache so we know we're getting # cached copy. key.delete() eventually(key.get, _equals(None)) retrieved = key.get() assert retrieved.foo == 42 assert retrieved.bar == "none"
def test_insert_entity_in_transaction_without_preallocating_id(dispose_of): class SomeKind(ndb.Model): foo = ndb.IntegerProperty() bar = ndb.StringProperty() def save_entity(): # By not waiting on the Future, we don't force a call to AllocateIds # before the transaction is committed. SomeKind(foo=42, bar="none").put_async() ndb.transaction(save_entity) query = SomeKind.query() eventually(query.fetch, length_equals(1)) retrieved = query.fetch()[0] dispose_of(retrieved._key._key) assert retrieved.foo == 42 assert retrieved.bar == "none"
def test_iter_all_of_a_kind(ds_entity): for i in range(5): entity_id = test_utils.system.unique_resource_id() ds_entity(KIND, entity_id, foo=i) class SomeKind(ndb.Model): foo = ndb.IntegerProperty() query = SomeKind.query().order("foo") results = eventually(lambda: list(query), _length_equals(5)) assert [entity.foo for entity in results] == [0, 1, 2, 3, 4]
def test_distinct_on(ds_entity): for i in range(6): entity_id = test_utils.system.unique_resource_id() ds_entity(KIND, entity_id, foo=i % 2, bar="none") class SomeKind(ndb.Model): foo = ndb.IntegerProperty() bar = ndb.StringProperty() query = SomeKind.query(distinct_on=("foo", )) eventually(SomeKind.query().fetch, _length_equals(6)) results = query.fetch() results = sorted(results, key=operator.attrgetter("foo")) assert results[0].foo == 0 assert results[0].bar == "none" assert results[1].foo == 1 assert results[1].bar == "none"
def test_query_structured_property(dispose_of): class OtherKind(ndb.Model): one = ndb.StringProperty() two = ndb.StringProperty() three = ndb.StringProperty() class SomeKind(ndb.Model): foo = ndb.IntegerProperty() bar = ndb.StructuredProperty(OtherKind) @ndb.synctasklet def make_entities(): entity1 = SomeKind(foo=1, bar=OtherKind(one="pish", two="posh", three="pash")) entity2 = SomeKind(foo=2, bar=OtherKind(one="pish", two="posh", three="push")) entity3 = SomeKind( foo=3, bar=OtherKind(one="pish", two="moppish", three="pass the peas"), ) keys = yield ( entity1.put_async(), entity2.put_async(), entity3.put_async(), ) return keys keys = make_entities() eventually(SomeKind.query().fetch, _length_equals(3)) for key in keys: dispose_of(key._key) query = (SomeKind.query().filter(SomeKind.bar.one == "pish", SomeKind.bar.two == "posh").order( SomeKind.foo)) results = query.fetch() assert len(results) == 2 assert results[0].foo == 1 assert results[1].foo == 2
def test_order_by_ascending(ds_entity): for i in reversed(range(5)): entity_id = test_utils.system.unique_resource_id() ds_entity(KIND, entity_id, foo=i) class SomeKind(ndb.Model): foo = ndb.IntegerProperty() query = SomeKind.query().order(SomeKind.foo) results = eventually(query.fetch, _length_equals(5)) assert [entity.foo for entity in results] == [0, 1, 2, 3, 4]
def test_namespace(dispose_of, other_namespace): class SomeKind(ndb.Model): foo = ndb.IntegerProperty() bar = ndb.StringProperty() entity1 = SomeKind(foo=1, bar="a", namespace=other_namespace) entity1.put() dispose_of(entity1.key._key) entity2 = SomeKind(foo=2, bar="b") entity2.put() dispose_of(entity2.key._key) eventually(SomeKind.query().fetch, _length_equals(1)) query = SomeKind.query(namespace=other_namespace) results = eventually(query.fetch, _length_equals(1)) assert results[0].foo == 1 assert results[0].bar == "a" assert results[0].key.namespace() == other_namespace