在交易中插入两个条目&获取'无法在事务中的不同实体组上运行'错误

时间:2011-07-01 15:33:25

标签: python google-app-engine transactions google-cloud-datastore

我的最终目标很简单。我需要一个具有两个独特的索引字段的实体,它们可以像键一样操作。如果这是一个SQL数据库,则equivelant将具有两个被定义为唯一且彼此独立的字段。我知道这个功能不可能直接用于一个数据存储db.Model,所以我必须创建一个模仿这种行为的父子模型场景。

为了解决这个问题,我创建了两个模型(ParentEntity和ChildEntity。)ParentEntity模型是一个 dummy db.Model,它存储两个键的两个值,但只有一个密钥已分配给模型#1的 key_name 参数。

创建父实体后,我通过将第二个键指定为 key_name 并将刚刚创建的父实体分配给子实体 parent 新的ChildEntity对象的构造函数中的参数。

我的假设是,这会将这些实体保留在同一个实体组中,因为这是谷歌文档所暗示的。

我已将一个名为 InsertData 的插入方法添加到ParentEntity(可以很容易地放在ChildEntity中),我可以调用它来控制此插入逻辑并尝试通过以下方式插入这些记录交易。

当我致电 InsertData 时,我收到以下错误:

  

无法对不同的实体进行操作   交易中的组:( kind ='ChildEntity',name ='key_name> 2')和(kind ='ParentEntity',name ='key_name 1')。

如果我的第二个(ChildEntity)实体被分配给参数的第一个实体(ParentEntity),那么这两个实体不应该在同一个实体组中吗?

提供的代码是我想要实现的功能的副本。唯一的区别是ChildEntity中存储了一些额外的属性,在txn()定义之前进行了一些数据验证,并且我已经将字段的名称更改为此问题的更有意义的名称。

class ParentEntity(db.Model):
    str1_key =  db.StringProperty()
    str2 =      db.StringProperty()

    @staticmethod
    def InsertData(string1, string2, string3):
        try:
            def txn():
                #create first entity
                prt = ParentEntity(
                    key_name=string1, 
                    str1_key=string1, 
                    str2=string2)
                prt.put()

                #create User Account Entity
                    child = ChildEntity(
                    key_name=string2, 
                    parent=prt, 
                    str1=string1, 
                    str2_key=string2,
                    str3=string3,)
                child.put()
                return child
            db.run_in_transaction(txn)
        except Exception, e:
            raise e

class ChildEntity(db.Model):
    #foreign and primary key values
    str1 =      db.StringProperty()
    str2_key =  db.StringProperty()

    #pertinent data below
    str3 =      db.StringProperty()

1 个答案:

答案 0 :(得分:2)

我已经解决了这个问题,但解决方案与上面提到的设置无关。正如我之前所说,我的实际类包含InsertData方法中的一些验证代码。验证逻辑的一部分是在txn()方法中进行的。我认为这不会是一个问题,因为我的所有验证都是检查以确保某些参数中有文本值,并且一个特定参数具有一定的长度。

从txn()方法移动验证后,插入操作没有问题。优良!