【问题标题】:Is it possible to have a db model and an ndb model in the same entity group?是否可以在同一个实体组中拥有一个 db 模型和一个 ndb 模型?
【发布时间】:2012-11-09 19:38:17
【问题描述】:

我们有一个 db 模型,Vote,我们已经使用了一段时间,最近添加了一个 ndb 模型,Score,它代表一个实体的累积分数,基于它的投票。目前Score 是其投票的父节点,因为我们希望它们都在同一个实体组中(因此它们可以在同一个事务中更新)。我一直在尝试让一个可以更新VoteScore 的事务工作,但它始终失败。下面是一些示例代码:

    def transaction():
        score = self.key_score.get()
        vote = db.get(self.key_vote)

        # do stuff

        score.put()
        vote.put()
    db.run_in_transaction(transaction)

据我所知(仅限开发服务器),这总是重试四次:

WARNING:root:Transaction collision. Retrying...
WARNING:root:Transaction collision. Retrying...
WARNING:root:Transaction collision. Retrying...
WARNING:root:Transaction collision. Retrying...
ERROR

然后我收到“TransactionFailedError:无法提交事务。请重试。”。

我已经尝试了一些方法来解决这个问题:

  1. 更改gets 和puts 的顺序 - 我认为可能存在我不理解的实体组锁定问题,但切换gets 或puts 的顺序并没有改变行为。

  2. 异步放置。这实际上是我开始的 - 我所知道的同时放置一个 db 和一个 ndb 模型的唯一方法(我认为这本质上是在幕后放置多个键所做的)。结果一样。

    score_future = score.put_async()
    vote_future = db.put_async(vote)
    score_future.get_result()
    vote_future.get_result()
    
  3. db.run_in_transaction 替换为ndb.transaction。这会在db.get 上引发“AttributeError:'Key' 对象没有属性'reference'”。我不确定这里发生了什么 - 看起来一些幕后代码正在获得 db.Key 它期望 ndb.Key

有趣的是,如果我删除 parent 关系,我可以运行与上面相同的代码,这意味着实体不在同一个实体组中。

那么,是否可以在同一个实体组中同时拥有 db 和 ndb 模型?也许有一种简单的方法可以将 db 模型作为 ndb 或反之亦然?

【问题讨论】:

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


    【解决方案1】:

    无论实体是使用 DB 还是 NDB 创建的,所有实体在数据存储中看起来都是一样的。这里的问题是您试图在 API 调用中混合两者;传递 ndb 模型实例时,db 不知道该怎么做。

    您需要为 Vote 创建一个与您的 db 模型相同的 NDB 模型 - 或者更好的是,将 Vote 迁移到 NDB 模型 - 并在您需要为两种实体类型进行事务的任何代码中使用它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多