使用NDB加载Appengine ext.db继承模型失败

时间:2014-10-29 05:07:33

标签: python google-app-engine google-cloud-datastore app-engine-ndb

使用NDB加载旧版ext.db继承模型失败,无法使用给定密钥检索对象或由于KindError异常而失败。

Live repro:http://ndb-key.appspot.com/

源存储库:https://github.com/lantius/ndb-key

db_class.py

from google.appengine.ext import db

class BaseClass(db.Model):
  name = db.StringProperty()

class DerivedClass(BaseClass):
  version = db.StringProperty()

ndb_class.py

from google.appengine.ext import ndb
from google.appengine.ext.ndb import polymodel

class BaseClass(polymodel.PolyModel):
  name = ndb.StringProperty()

class DerivedClass(BaseClass):
  version = ndb.StringProperty()

repro.py

import webapp2

from google.appengine.ext import db  
from google.appengine.ext import ndb

from db_class import DerivedClass as OldDerivedClass
from ndb_class import BaseClass as NewBaseClass
from ndb_class import DerivedClass as NewDerivedClass


class Repro(webapp2.RequestHandler):
  def get(self):
    self.response.headers['Content-Type'] = 'text/plain'

    # Create a derived object using google.appengine.ext.db
    obj = OldDerivedClass(name='foo', version='bar')
    db_key = obj.put()
    self.response.write('%s, %d\n' % (db_key.kind(), db_key.id()))

    # Attempt to load using the converted key
    ndb_key = ndb.Key.from_old_key(db_key)
    try:
      ndb_key.get()
    except ndb.KindError:
      self.response.write('failed (KindError): %s\n' % str(ndb_key))

    # Attempt to create a new key using the ndb derived class
    derived_key = ndb.Key(NewDerivedClass, ndb_key.id())
    obj = derived_key.get()
    if not obj:
      self.response.write('failed (None): %s\n' % str(derived_key))

    # Attempt to create a new key using the ndb base class
    base_key = ndb.Key(NewBaseClass, ndb_key.id())
    obj = derived_key.get()
    if not obj:
      self.response.write('failed (None): %s\n' % str(base_key))

    # Manually create a new key using the ndb derived class name
    force_key = ndb.Key('DerivedClass', ndb_key.id())
    try:
      force_key.get()
    except ndb.KindError:
      self.response.write('failed (KindError): %s\n' % str(force_key))

application = webapp2.WSGIApplication([('/', Repro)], debug=True)

1 个答案:

答案 0 :(得分:0)

我的错误是原始模型继承自db.Model,而不是db.Polymodel,这意味着密钥是合法的不同。

转换为ndb.Polymodel是由于NDB中的密钥类型更强,这使得尝试为ndb.KeyProperty使用基类时出错。