V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
DAOCLOUD
推荐学习书目
Python Cookbook
Using Google App Engine
推荐下载
Latest Google App Engine SDK
其他兼容技术
AppScale
darasion
V2EX  ›  Google App Engine

实体的 id、 key_name 以及 path 都有什么用?

  •  
  •   darasion · 2010-12-31 18:17:46 +08:00 · 4988 次点击
    这是一个创建于 5087 天前的主题,其中的信息可能已经有所发展或是发生改变。
    一直搞不懂为啥要这样做。

    在存在实体组的情况下,Model.get_by_id() 和 Model.get_by_key_name 都必须指定 parent 才能正确获得实体。而是用Model.get()则可以直接通过key来获取实体。那么为什么还用那个数字的id或者是字符串的key_name呢?是为了是用起来记着方便呢,还是要实现实体组这些东西必须这样做呢?

    如果是为了是用起来记着方便,那为什么还必须写出完整路径(path)才能获取实体??例如:Model.get_by_id(123, parent=db.Key('xxxxxx'))

    另外就是不知道 path 在实体组的操作上有什么不可替代的作用呢?
    10 条回复    1970-01-01 08:00:00 +08:00
    ayanamist
        1
    ayanamist  
       2010-12-31 18:43:30 +08:00
    谁说get_by_id和get_by_key_name要指定parent的?麻烦你再去看看文档吧……
    另外get_by_id的速度是最快的,主要是性能上的差距吧
    darasion
        2
    darasion  
    OP
       2010-12-31 18:52:02 +08:00
    @ayanamist “在存在实体组的情况下”,必须指定parent,否则返回 None。这个我实测过,你实测过吗?
    darasion
        3
    darasion  
    OP
       2010-12-31 18:58:53 +08:00
    假设:
    class A(db.Model):
    #...

    class B(db.Model):
    #...


    若:
    a=A()
    a.put()

    b=B(parent=a)
    b.put()


    1、那么已知 b 的 id :

    运行 B.get_by_id(id, parent=a)
    返回 b

    运行 B.get_by_id(id)
    返回 None,或者其他不是b的实体。


    2、已知b 的 key:

    B.get(key) 或 db.get(key) 都可以
    返回 b
    ayanamist
        4
    ayanamist  
       2010-12-31 19:39:16 +08:00
    @darasion 你创建Model的时候指定了parent,后面调用自然也要有parent……文档里很清楚的写了。另外你写个“存在实体组的情况下”,我真不明白这句话。我看的是英文文档。
    文档里对你的问题描述的很清楚,因为可以有重名但不同parent的情况。
    http://code.google.com/appengine/docs/python/datastore/keysandentitygroups.html
    The keys of two different entities can have similar parts as long as at least one part is different. For instance, two entities can have the same kind and name if they have different parents. Similarly, two entities can have the same parent (or no parent) and name if they are of different kinds.
    ayanamist
        5
    ayanamist  
       2010-12-31 19:40:08 +08:00
    @darasion 其实这个Entity Group作用很有限。文档里也写了
    Only use entity groups when they are needed for transactions. For other relationships between entities, use ReferenceProperty properties and Key values, which can be used in queries.
    darasion
        6
    darasion  
    OP
       2010-12-31 20:10:13 +08:00
    @ayanamist 我问的是为什么要这样做,而不是怎样做。怎样做我知道。

    你 #4 中提到的文档段落我都看了。关键是为什么?

    知其然,还要知其所以然嘛。

    你 #5 中提到的文档段落我也都看到了。没错,我就是在这里需要一个事务性的删除。
    keakon
        7
    keakon  
       2010-12-31 21:37:02 +08:00
    简单来说,key和path是一回事,key只是将path(元组列表)编码成字符串了而已。

    所以你的问题没什么好解释的,get一个实体使用完整的path本来就是必须的。get_by_id、get_by_key_name和get是完全等效的,最终都是通过key来获取。

    有的时候你只想取根实体,那么通过path去构造key就显得太麻烦了,所以才会去用上述简写。有时你已经拿到父实体的key了,那么再去构造完整的path也显得多余。
    ayanamist
        8
    ayanamist  
       2011-01-01 09:15:40 +08:00
    @keakon get_by_id不是通过key来获取的吧……
    keakon
        9
    keakon  
       2011-01-01 11:50:07 +08:00
    @ayanamist
    源码摆在SDK里,你自己看看就知道了:
    @classmethod
    def get_by_id(cls, ids, parent=None, **kwargs):
    """Get instance of Model class by id.

    Args:
    key_names: A single id or a list of ids.
    parent: Parent of instances to get. Can be a model or key.
    config: datastore_rpc.Configuration to use for this request.
    """
    config = datastore._GetConfigFromKwargs(kwargs)
    if isinstance(parent, Model):
    parent = parent.key()
    ids, multiple = datastore.NormalizeAndTypeCheck(ids, (int, long))
    keys = [datastore.Key.from_path(cls.kind(), id, parent=parent)
    for id in ids]
    if multiple:
    return get(keys, config=config)
    else:
    return get(keys[0], config=config)

    一个实体在存储到datastore的时候,最多需要保存到3种类型的表,但没有任何一种表的任何一个字段是其id或key name,所有的表都只存储编码后的key。这就是为什么不可能不用key来获取实体的原因。

    顺带一提,即使是query,也是查询索引表或自定义索引表,获得key,然后再到实体表获取key对应的实体。
    darasion
        10
    darasion  
    OP
       2011-01-02 17:54:32 +08:00
    @keakon 谢谢。又加深了一些理解。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   6005 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 02:07 · PVG 10:07 · LAX 18:07 · JFK 21:07
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.