使用Google Datastore / Python NDB的交易系统中的多对多关系

时间:2014-10-20 08:57:21

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

我正在为一家农作物仓储公司撰写申请,该公司购买收获的农作物并将其存放在一个或多个仓库中。到目前为止,Google App Engine / Datastore的限制对我来说并没有什么问题。而且我对项目的深入了解很难回归。

我必须在两个 Kinds 之间建立多对多关系,它们本质上是事务性的(意味着父/祖先查询)。我不确定这样做的正确方法是什么。这是业务逻辑:

  1. 仓库发出特定数量(PO)的采购订单。因此,我们为每个采购订单(PO)在 PO Kind 中创建一个实体。

  2. 货物在仓库收到。所以我们在 GRN Kind 中创建一个实体。 (GRN =收货单)。

  3. 这是很多很多关系。

    1. 可能需要一个GRN才能完成一个采购订单。

    2. 可能需要一个GRN来完成许多PO。

    3. 可能需要许多GRN才能完成一个采购订单。

    4. 可能需要许多GRN才能完成许多采购订单。

    5. 这是代码的相关快照。

      class Warehouse(ndb.Models):
          name = ndb.TextProperty()
          capacity = ndb.FloatProperty()
          current_stock = ndb.FloatProperty()
      
      class PurchaseOrder(ndb.Models):
          quantity = ndb.FloatProperty()
          remaining = ndb.FloatProperty()
          is_complete = ndb.BooleanProperty()
          grn = ndb.KeyProprty(repeated=True, kind=GRN)
      
      class GRN(ndb.Models):
          quantity = ndb.FloatProperty()
          remaining = ndb.FloatProperty()
          is_complete = ndb.BooleanProperty()
          po = ndb.KeyProprty(repeated=True, kind=PurchaseOrder)
      

      实体组关系

      仓库 - > GRN

      仓库 - > PO

      为了建立多对多关系,我将PO记录中的所有相关GRN密钥和GRN记录中的所有相关PO密钥保存在一起。这对我来说很好。

      但是如果我必须在后期修改GRN或PO,那么我无法处理可能影响其他GRN和PO的级联更改的复杂性。

      • 我读到的某个地方我应该使用第三个模型来保持多对多的关系,而不是存储相关的密钥。我无法想象应该包含的第三个表。 *

      我知道我的问题非常具体,而且我没有把所有细节都搞定。但只是帮助我找到这种问题模式的正确方法。我将处理剩下的事情。或者提供任何链接,如果已经在某处记录过。

1 个答案:

答案 0 :(得分:1)

我会添加一个名为GRNinstance的多对多关系,它将单个GRN实例与单个PO链接:

class PurchaseOrder(ndb.Models):
    quantity = ndb.FloatProperty()
    remaining = ndb.FloatProperty()
    is_complete = ndb.BooleanProperty()

class GRN(ndb.Models):
    quantity = ndb.FloatProperty()
    remaining = ndb.FloatProperty()
    is_complete = ndb.BooleanProperty()

class GRNinstance(ndb.Models):
    po = ndb.KeyProperty(kind=PurchaseOrder)
    grn = ndb.KeyProperty(kind=GRN)
    quantity = ndb.FloatProperty()

特定GRNinstance.quantity的{​​{1}}总和最多为po,特定PurchaseOrder.quantity的{​​{1}}总和应加起来GRNinstance.quantity

事实上,德米特里的grn可以取代GRN.quantityComputedProperty(但这可能会很慢)。也许PurchaseOrder.quantity可能是一个简单的测试:

GRN.quantity