追溯NDB中的未知种类 [英] Following backreferences of unknown kinds in NDB

查看:121
本文介绍了追溯NDB中的未知种类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写GAE和Python 2.7运行时的第一个RESTful Web服务;我已经开始使用Guido的闪亮的新的ndb API。然而,我不确定如何解决一个特定的情况,没有原始数据库的隐式反向引用特性API。如果用户代理请求特定的资源并删除1度的资源:

host / api / kind / id?depth = 2



考虑到在开发时相关实体的类型是未知的,在一对多关系中发现一个相关实体集合的最好方法是什么?




  • 我无法使用以前的SO查询。事实上,我的模型在运行时是可定义的(因此没有硬编码),这使我无法使用查询来过滤匹配键的属性。

  • 祖先和其他无情的查询也由于数据存储区限制而无法使用,这些限制阻止了我在没有指定类型的情况下对属性进行过滤。 >到目前为止,我唯一的想法(除了恢复到db api之外)是使用跨组事务在one上编写自己的引用,或者通过更新ndb.StringProperty(repeat = True)当引入新类型的实体时包含所有相关类型,或者每次将相关的many实体写入数据存储时,通过简单地在onendb.KeyProperty(repeat = True)上维护一个键列表。 / p>

    我希望有人比我更有经验可以提出更好的方法。



    鉴于jmort253的建议,我会用一个具体的例子来改进我的问题文档:

    $ $ p $ class Contact(ndb.Expando):
    The One

    #基本信息
    名字= ndb.StringProperty()
    birth_day = ndb.DateProperty()

    #如果我使用db,一个名为'phone_numbers '会隐式地在这里创建
    #。我可以在查询此实体时使用此属性检索相关电话号码
    #。由于NDB缺乏这种功能,服务
    #既不会有查询的引用,也无法知道
    #关系,因为它不能被硬编码。
    #数据模型在运行时是可扩展的和用户定义的;大多数关系
    #将仅在数据中描述,并且必须由服务器发现。
    #在这种情况下,当查询联系人时,我需要一种方法来检索
    #电话号码集合。

    #公司信息。
    company_title = ndb.StringProperty()
    company_name = ndb.StringProperty()
    company_description = ndb.StringProperty()
    company_address = ndb.PostalAddressProperty()

    class PhoneNumber(ndb.Expando):
    Many

    #no collection_name ='phone_numbers'等同于键属性
    contact = ndb .KeyProperty(kind ='Contact')
    number = ndb.PhoneNumberProperty()


    解决方案

    有趣的问题!所以基本上你想看看Contact类,看看是否有其他的模型类有一个KeyProperty引用它;在这个例子中PhoneNumber(但可能有很多)。

    我认为解决方案是让你的用户在创建PhoneNumber类时显式地添加这个链接。

    p>

    通过为用户提供一个KeyProperty的子类来处理这个问题,例如

      class LinkedKeyProperty(ndb.KeyProperty):
    def _fix_up(self,cls,code_name):
    super(LinkedKeyProperty,self)._ fix_up(cls,code_name)
    modelclass = ndb.Model._kind_map [self._kind]
    collection_name ='%s_ref_%s_to_%s'%(cls .__ name__,
    code_name,
    modelclass .__ name__)
    setattr(modelclass,collection_name,(cls,self))

    准确地说,您如何为集合选择名称以及存储的价值取决于您;只需在那里放置一些东西,便于您轻松链接。这个例子会在联系人上创建一个新的属性:

      Contact.PhoneNumber_ref_contact_to_Contact ==(PhoneNumber,PhoneNumber.contact)


    I'm in the process of writing my first RESTful web service atop GAE and the Python 2.7 runtime; I've started out using Guido's shiny new ndb API.

    However, I'm unsure how to solve a particular case without the implicit back-reference feature of the original db API. If the user-agent requests a particular resource and those resources 1 degree removed:

    host/api/kind/id?depth=2

    What's the best way to discover a related collection of entities from the "one" in a one-to-many relationship, given that the kind of the related entity is unknown at development time?

    • I'm unable to use a replacement query as described in a previous SO inquiry due to the latter restriction. The fact that my model is definable at runtime (and therefore isn't hardcoded) prevents me from using a query to filter properties for matching keys.

    • Ancestor and other kindless queries are also out due to the datastore limitation that prevents me from filtering on a property without the kind specified.

    Thus far, the only idea I've had (beyond reverting to the db api) is to use a cross-group transaction to write my own reference on the "one", either by updating an ndb.StringProperty(repeat=True) containing all the related kinds when an entity of a new kind is introduced or by simply maintaining a list of keys on the "one" ndb.KeyProperty(repeat=True) every time a related "many" entity is written to the datastore.

    I'm hoping someone more experienced than myself can suggest a better approach.

    Given jmort253's suggestion, I'll try to augment my question with a concrete example adapted from the docs:

    class Contact(ndb.Expando):
        """ The One """
    
        # basic info
        name = ndb.StringProperty()
        birth_day = ndb.DateProperty()
    
        # If I were using db, a collection called 'phone_numbers' would be implicitly 
        # created here.  I could use this property to retrieve related phone numbers 
        # when this entity was queried.  Since NDB lacks this feature, the service 
        # will neither have a reference to query nor the means to know the 
        # relationship exists in the first place since it cannot be hard-coded.  The
        # data model is extensible and user-defined at runtime; most relationships
        # will be described only in the data, and must be discoverable by the server.
        # In this case, when Contact is queried, I need a way to retrieve the
        # collection of phone numbers.
    
        # Company info.
        company_title = ndb.StringProperty()
        company_name = ndb.StringProperty()
        company_description = ndb.StringProperty()
        company_address = ndb.PostalAddressProperty()
    
    class PhoneNumber(ndb.Expando):
        """ The Many """
    
        # no collection_name='phone_numbers' equivalent exists for the key property
        contact = ndb.KeyProperty(kind='Contact')
        number = ndb.PhoneNumberProperty()
    

    解决方案

    Interesting question! So basically you want to look at the Contact class and find out if there is some other model class that has a KeyProperty referencing it; in this example PhoneNumber (but there could be many).

    I think the solution is to ask your users to explicitly add this link when the PhoneNumber class is created.

    You can make this easy for your users by giving them a subclass of KeyProperty that takes care of this; e.g.

    class LinkedKeyProperty(ndb.KeyProperty):
        def _fix_up(self, cls, code_name):
            super(LinkedKeyProperty, self)._fix_up(cls, code_name)
            modelclass = ndb.Model._kind_map[self._kind]
            collection_name = '%s_ref_%s_to_%s' % (cls.__name__,
                                                   code_name,
                                                   modelclass.__name__)
            setattr(modelclass, collection_name, (cls, self))
    

    Exactly how you pick the name for the collection and the value to store there is up to you; just put something there that makes it easy for you to follow the link back. The example would create a new attribute on Contact:

    Contact.PhoneNumber_ref_contact_to_Contact == (PhoneNumber, PhoneNumber.contact)
    

    [edited to make the code working and to add an example. :-) ]

    这篇关于追溯NDB中的未知种类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆