File tree Expand file tree Collapse file tree 2 files changed +50
-1
lines changed
packages/google-cloud-ndb Expand file tree Collapse file tree 2 files changed +50
-1
lines changed Original file line number Diff line number Diff line change @@ -1687,7 +1687,23 @@ def _validate(self, value):
16871687 """
16881688 methods = self ._find_methods ("_validate" , "_to_base_type" )
16891689 call = self ._apply_list (methods )
1690- return call (value )
1690+ value = call (value )
1691+
1692+ # Legacy NDB, because it didn't delegate to Datastore for serializing
1693+ # entities, would directly write a Key protocol buffer for a key. We,
1694+ # however, need to transform NDB keys to Datastore keys before
1695+ # delegating to Datastore to generate protocol buffers. You might be
1696+ # tempted to do this in KeyProperty._to_base_type, and that works great
1697+ # for properties of KeyProperty type. If, however, you're computing a
1698+ # key in a ComputedProperty, ComputedProperty doesn't know to call
1699+ # KeyProperty's base type. (Probably ComputedProperty should take
1700+ # another property type as a constructor argument for this purpose,
1701+ # but that wasn't part of the original design and adding it introduces
1702+ # backwards compatibility issues.) See: Issue #184
1703+ if isinstance (value , key_module .Key ):
1704+ value = value ._key # Datastore key
1705+
1706+ return value
16911707
16921708 def _call_shallow_validation (self , value ):
16931709 """Call the "initial" set of ``_validate()`` methods.
Original file line number Diff line number Diff line change @@ -1004,3 +1004,36 @@ class SomeKind(ndb.Model):
10041004
10051005 key .delete ()
10061006 assert key .get () is None
1007+
1008+
1009+ @pytest .mark .usefixtures ("client_context" )
1010+ def test_computed_key_property (dispose_of ):
1011+ """Regression test for #284.
1012+
1013+ https://github.com/googleapis/python-ndb/issues/284
1014+ """
1015+
1016+ class AModel (ndb .Model ):
1017+ s_foo = ndb .StringProperty ()
1018+
1019+ class BModel (ndb .Model ):
1020+ s_bar = ndb .StringProperty ()
1021+ key_a = ndb .KeyProperty (kind = "AModel" , indexed = True )
1022+
1023+ class CModel (ndb .Model ):
1024+ s_foobar = ndb .StringProperty ()
1025+ key_b = ndb .KeyProperty (kind = "BModel" , indexed = True )
1026+ key_a = ndb .ComputedProperty ( # Issue here
1027+ lambda self : self .key_b .get ().key_a if self .key_b else None ,
1028+ )
1029+
1030+ key_a = AModel (s_foo = "test" ).put ()
1031+ dispose_of (key_a ._key )
1032+ key_b = BModel (s_bar = "test" , key_a = key_a ).put ()
1033+ dispose_of (key_b ._key )
1034+ key_c = CModel (s_foobar = "test" , key_b = key_b ).put ()
1035+ dispose_of (key_c ._key )
1036+
1037+ entity = key_c .get ()
1038+ assert entity .key_a == key_a
1039+ assert entity .key_b == key_b
You can’t perform that action at this time.
0 commit comments