是否可以在同一实体组中使用db模型和ndb模型?

Joe*_*get 2 google-app-engine app-engine-ndb

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

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

        # do stuff

        score.put()
        vote.put()
    db.run_in_transaction(transaction)
Run Code Online (Sandbox Code Playgroud)

从我所知道的(仅限dev服务器),这总是重试四次:

WARNING:root:Transaction collision. Retrying...
WARNING:root:Transaction collision. Retrying...
WARNING:root:Transaction collision. Retrying...
WARNING:root:Transaction collision. Retrying...
ERROR
Run Code Online (Sandbox Code Playgroud)

然后我得到"TransactionFailedError:交易无法提交.请再试一次.".

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

  1. 更改获取和放置的顺序 - 我想也许有一个实体组锁定问题,我不明白,但切换获取或放置的顺序并没有改变行为.

  2. 异步投入.这实际上就是我开始的 - 我知道同时放置db和ndb模型的唯一方法(我认为这实际上是在幕后放置多个键的原因).结果相同.

    score_future = score.put_async()
    vote_future = db.put_async(vote)
    score_future.get_result()
    vote_future.get_result()
    
    Run Code Online (Sandbox Code Playgroud)
  3. 替换db.run_in_transactionndb.transaction.抛出"AttributeError:'Key'对象没有属性'reference'" db.get.我不确定这里发生了什么 - 看起来一些幕后代码正在db.Key达到预期的水平ndb.Key.

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

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

Nic*_*son 5

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

您需要创建一个与您的投票数据库模型相同的NDB模型 - 或者更好的是,将投票迁移到NDB模型 - 并在需要两种实体类型的事务的任何代码中使用它.