在事务中插入两个实体&获取“无法在事务中对不同实体组进行操作”错误

发布于 2024-11-17 20:56:17 字数 2055 浏览 2 评论 0原文

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

为了解决这个问题,我创建了两个模型(ParentEntity 和 ChildEntity)。ParentEntity 模型是一个虚拟 db.Model,它存储两个键的两个值,但只分配了其中一个键到模型 #1 的 key_name 参数。

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

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

我向 ParentEntity 添加了一个名为 InsertData 的插入方法(可以轻松地将其放置在 ChildEntity 中),我可以调用该方法来控制此插入逻辑,并尝试通过事务插入这些记录。

当我调用 InsertData 时,出现以下错误:

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

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

提供的代码是我想要实现的功能的功能副本。唯一的区别是一些额外的属性存储在 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()

My end goal is simple. I need to have an entity that has two, unique, indexed fields that can operate like keys. If this was a SQL database, the equivelant would be having two fields that are defined as both unique and are independant of one another. I know this functionality isn't directly possible for one data store db.Model, so I've had to create a parent-child Model scenario that mimics this behavior.

To solve this problem, I've created two Models (ParentEntity and ChildEntity.) The ParentEntity model is a dummy db.Model that stores the two values of the two keys but only one of the keys is assigned to the key_name parameter of Model #1.

After creating the parent entity, I create the second, child entity by assigning the second key as the key_name and assigning the parent entity I just created to the child entities parent parameter in the constructor of the new ChildEntity object.

My assumption is that this would keep these entities within the same entity group because that is what the google documentation implies.

I've added an insertion method named InsertData to the ParentEntity (which could just as easily be placed in the ChildEntity) which I can call to control this insertion logic and attempts to insert these records via a transaction.

When I call InsertData I get the follow error:

Cannot operate on different entity
groups in a transaction: (kind='ChildEntity', name='key_name > 2') and (kind='ParentEntity', name='key_name 1').

If my second (ChildEntity) entity is assigned the first entity (ParentEntity) to the parent parameter, shouldn't these two entities be in the same entity group?

The code provided is a functional copy of what I am trying to achieve. The only difference is that a few extra properties are stored in ChildEntity, a bit of data validation takes place before txn() definition and I've changed the names of the fields to more meaningful names for this question.

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()

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

客…行舟 2024-11-24 20:56:17

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

在我将验证从 txn() 方法中移出后,插入操作就没有问题了。出色的!

I've fixed this problem but it the solution is unrelated to the setup mentioned above. As I had previously stated, my actual class contains some validation code within the InsertData method. Portions of the Validation logic were taking place in the txn() method. I assumed that this wouldn't be a problem because all my validation does is check to be sure that there are text values within certain parameters and that one specific parameter is of a certain length.

After I moved the validation from the txn() method, the insertion operation has worked without a problem. Excellent!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文