Skip to content

Commit c6bf97c

Browse files
author
Chris Rossi
authored
Three easy Model methods. (#94)
``Model.populate``, ``Model.has_complete_key``, ``Model.to_dict``.
1 parent 128ae01 commit c6bf97c

File tree

2 files changed

+128
-0
lines changed

2 files changed

+128
-0
lines changed

packages/google-cloud-ndb/src/google/cloud/ndb/model.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4687,6 +4687,60 @@ def insert():
46874687

46884688
get_or_insert_async = _get_or_insert_async
46894689

4690+
def _populate(self, **kwargs):
4691+
"""Populate an instance from keyword arguments.
4692+
4693+
Each keyword argument will be used to set a corresponding property.
4694+
Each keyword must refer to a valid property name. This is similar to
4695+
passing keyword arguments to the ``Model`` constructor, except that no
4696+
provision for key, id, or parent are made.
4697+
4698+
Arguments:
4699+
**kwargs: Keyword arguments corresponding to poperties of this
4700+
model class.
4701+
"""
4702+
self._set_attributes(kwargs)
4703+
4704+
populate = _populate
4705+
4706+
def _has_complete_key(self):
4707+
"""Return whether this entity has a complete key.
4708+
4709+
Returns:
4710+
bool: :data:``True`` if and only if entity has a key and that key
4711+
has a name or an id.
4712+
"""
4713+
return self._key is not None and self._key.id() is not None
4714+
4715+
has_complete_key = _has_complete_key
4716+
4717+
def _to_dict(self, include=None, *, exclude=None):
4718+
"""Return a ``dict`` containing the entity's property values.
4719+
4720+
Arguments:
4721+
include (Optional[Union[list, tuple, set]]): Set of property names
4722+
to include. Default is to include all names.
4723+
exclude (Optional[Union[list, tuple, set]]): Set of property names
4724+
to exclude. Default is to not exclude any names.
4725+
"""
4726+
values = {}
4727+
for prop in self._properties.values():
4728+
name = prop._code_name
4729+
if include is not None and name not in include:
4730+
continue
4731+
if exclude is not None and name in exclude:
4732+
continue
4733+
4734+
try:
4735+
values[name] = prop._get_for_dict(self)
4736+
except UnprojectedPropertyError:
4737+
# Ignore unprojected property errors, rather than failing
4738+
pass
4739+
4740+
return values
4741+
4742+
to_dict = _to_dict
4743+
46904744

46914745
class Expando(Model):
46924746
__slots__ = ()

packages/google-cloud-ndb/tests/unit/test_model.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3347,6 +3347,80 @@ class Simple(model.Model):
33473347

33483348
key.get_async.assert_called_once_with(_options=_options.ReadOptions())
33493349

3350+
@staticmethod
3351+
def test_populate():
3352+
class Simple(model.Model):
3353+
foo = model.IntegerProperty()
3354+
bar = model.StringProperty()
3355+
3356+
entity = Simple()
3357+
entity.populate(foo=3, bar="baz")
3358+
3359+
assert entity.foo == 3
3360+
assert entity.bar == "baz"
3361+
3362+
@staticmethod
3363+
def test_has_complete_key_no_key():
3364+
class Simple(model.Model):
3365+
pass
3366+
3367+
entity = Simple()
3368+
assert not entity.has_complete_key()
3369+
3370+
@staticmethod
3371+
@pytest.mark.usefixtures("in_context")
3372+
def test_has_complete_key_incomplete_key():
3373+
class Simple(model.Model):
3374+
pass
3375+
3376+
entity = Simple(key=key_module.Key("Simple", None))
3377+
assert not entity.has_complete_key()
3378+
3379+
@staticmethod
3380+
@pytest.mark.usefixtures("in_context")
3381+
def test_has_complete_key_complete_with_id():
3382+
class Simple(model.Model):
3383+
pass
3384+
3385+
entity = Simple(id="happiness")
3386+
assert entity.has_complete_key()
3387+
3388+
@staticmethod
3389+
def test_to_dict():
3390+
class Simple(model.Model):
3391+
foo = model.IntegerProperty()
3392+
bar = model.StringProperty()
3393+
3394+
entity = Simple(foo=3, bar="baz")
3395+
assert entity.to_dict() == {"foo": 3, "bar": "baz"}
3396+
3397+
@staticmethod
3398+
def test_to_dict_with_include():
3399+
class Simple(model.Model):
3400+
foo = model.IntegerProperty()
3401+
bar = model.StringProperty()
3402+
3403+
entity = Simple(foo=3, bar="baz")
3404+
assert entity.to_dict(include={"foo"}) == {"foo": 3}
3405+
3406+
@staticmethod
3407+
def test_to_dict_with_exclude():
3408+
class Simple(model.Model):
3409+
foo = model.IntegerProperty()
3410+
bar = model.StringProperty()
3411+
3412+
entity = Simple(foo=3, bar="baz")
3413+
assert entity.to_dict(exclude=("bar",)) == {"foo": 3}
3414+
3415+
@staticmethod
3416+
def test_to_dict_with_projection():
3417+
class Simple(model.Model):
3418+
foo = model.IntegerProperty()
3419+
bar = model.StringProperty()
3420+
3421+
entity = Simple(foo=3, bar="baz", projection=("foo",))
3422+
assert entity.to_dict() == {"foo": 3}
3423+
33503424

33513425
class Test_entity_from_protobuf:
33523426
@staticmethod

0 commit comments

Comments
 (0)