8000 Cannot read entity as PolyModel subclass from LocalStructuredProperty · Issue #481 · googleapis/python-ndb · GitHub
[go: up one dir, main page]

Skip to content
Cannot read entity as PolyModel subclass from LocalStructuredProperty #481
@MisarteWork

Description

@MisarteWork

Environment details

  1. google-cloud-ndb 1.4.0
  2. Python 2.7 (have tested with Python 3 as well)

Steps to reproduce

The following test of a LocalStructuredProperty containing a subclass of PolyModel fails with "AttributeError", whereas the equivalent test using the old NDB library passes.

The value of the LocalStructuredProperty is an instance of the subclass (Child), which we are unable to read.

Code example

# example (using cloud-ndb)
from google.cloud import ndb
import pytest
@pytest.fixture(scope="function")
def client_context():
    client = ndb.Client()
    with client.context():
        yield
class Base(ndb.PolyModel):
    pass
class Child(Base):
    val = ndb.StringProperty()
class Composite(ndb.Model):
    non_local = ndb.StructuredProperty(Base)
    local = ndb.LocalStructuredProperty(Base)
@pytest.mark.usefixtures('client_context')
def test():
    c = Composite(non_local=Child(val="a"), local=Child(val="b"))
    c.put()
    c = c.key.get()

    assert c.non_local.val == "a" # True
    assert c.local.val == "b" # AttributeError: 'Base' object has no attribute 'val'
# example (using old library which works)
from google.appengine.ext import ndb, testbed as tb
from google.appengine.ext.ndb import polymodel
import pytest
@pytest.fixture(scope="function")
def gae():
    testbed = init_testbed()
    yield
    teardown_testbed(testbed)
def init_testbed():
    testbed = tb.Testbed()
    testbed.activate()
    testbed.init_memcache_stub()
    testbed.init_datastore_v3_stub()
    testbed.init_urlfetch_stub()
    context = ndb.get_context()
    context.set_memcache_policy(False)
    return testbed
def teardown_testbed(testbed):
    testbed.deactivate()
class Base(polymodel.PolyModel):
    pass
class Child(Base):
    val = ndb.StringProperty()
class Composite(ndb.Model):
    non_local = ndb.StructuredProperty(Base)
    local = ndb.LocalStructuredProperty(Base)
@pytest.mark.usefixtures('gae')
def test():
    c = Composite(non_local=Child(val="a"), local=Child(val="b"))
    c.put()
    c = c.key.get()
    assert c.non_local.val == "a" # True
    assert c.local.val == "b" # True

Testing the initial example (with new Cloud NDB library) with another test.py using print we receive the screenshot below:

def test():
 c = Composite(non_local=Child(val="a"), local=Child(val="b"))
 
 print c.non_local.__dict__
 print c.local.__dict__

 c.put()
 c = c.key.get()

 print c.non_local.__dict__
 print c.local.__dict__

 assert c.non_local.val == "a" # True
 assert c.local.val == "b" # AttributeError: 'Base' object has no attribute 'val'

PrintsBefore-After-Put-GetMethods

Testing with Legacy-Data = False we receive results screenshot below:

PrintsLegacyData-False

Metadata

Metadata

Assignees

Labels

🚨This issue needs some love.api: datastoreIssues related to the googleapis/python-ndb API.priority: p1Important issue which blocks shipping the next release. Will be fixed prior to next release.type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions

    0