【问题标题】:Google Datastore deletes and multiple parents谷歌数据存储删除和多个父母
【发布时间】:2017-09-11 01:48:30
【问题描述】:

我有一个数据模型,其中实体A 包含对其他两个实体BC 的引用。如果BC 被删除,我希望A 被删除。

创建A 时,可以将BC 命名为其父级。是否也可以将 both BC 命名为其父级,这样如果 BC 被删除,A 也会被删除?

更具体地说,比如搜索结果,一个结果可能同时包含categoryregion,比如关于北美鸟类的网页。结果与对其类别和区域的引用一起存储。稍后,您想要删除类别birds,并且您希望结果也被删除。同样,您删除区域North America 并希望删除结果。

我讨厌对这样一个琐碎的场景进行如此冗长的讨论。但它似乎没有包含在任何 Datastore 文档中。我错过了什么?它是一个基本有缺陷的数据模型吗?

【问题讨论】:

    标签: google-cloud-datastore data-modeling


    【解决方案1】:

    单亲限制:

    数据存储区中一个子级只能有一个父级。换句话说,A 只能是 B OR C 的孩子,不能同时是两者。当然,父母可以有多个孩子。

    替代方案:

    您可以使用 KeyPropertyrepeated=True 参数并在其上存储许多实体键。在 Python 中,这将是这样的:

    class A(ndb.Model):
        associated_with = ndb.KeyProperty(repeated=True)
        some_other_property = ndb.StringProperty()
    
    a_entity = A(
        associated_with = [b_key, c_key],
        some_other_property = 'any value'
    )
    a_entity.put()
    

    自动触发删除:

    Datastore 不提供开箱即用的此功能,但您可以在应用程序中模仿它。在 Python 中实现的一个想法,例如,您可以使用自己的 delete 方法扩展 Model 类(尚未测试此代码,仅用于说明):

    class A(ndb.Model):
        associated_with = ndb.KeyProperty(repeated=True)
        some_other_property = ndb.StringProperty()
    
        def delete_ext(entity):  # entity object
            if entity.associated_with:
                for associated in entity.associated_with:
                    associated.delete()
            entity.key.delete()
    

    您可能希望将所有删除操作包装在一个事务中。请注意,单个事务最多可以对 25 个实体组进行操作。

    【讨论】:

    • 啊,谢谢。正如我所怀疑的,使用repeated 属性对域建模更正确。这也比尝试使用单个实体引用将模型挂在一起更直观。回到绘图板...
    • 只是想知道...delete_ext 中“_ext”的用途是什么?为了防止递归或与模型命名空间冲突?
    • 不需要添加“_ext”。在 Python NDB 库中,Model class 没有名为 delete 的方法,您可以使用它。就个人而言,我会添加一些与 Key delete() 方法区分开来的东西,但这只是为了帮助避免我自己(或将来的任何人)将自定义 A.delete() 方法与 A.key.delete() 混淆阅读代码时。
    • 对我来说似乎很合理。谢谢。
    猜你喜欢
    • 2019-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多