首先进行一些设置。上周,我在实现我构建的一种特定方法时遇到了麻烦,该方法允许我管理与一个 db.Model 对象关联的两个唯一字段。由于这是不可能的,因此我创建了一个父实体类和一个子实体类,每个类都为 key_name 分配了一个唯一值。你可以找到我之前的问题位于这里 https://stackoverflow.com/questions/6550029/inserting-two-enties-in-a-transaction-getting-cannot-operate-on-different-enti,其中包括我的示例代码和我的插入过程的一般说明。
关于我最初的问题,有人评论说我的解决方案无法解决我需要与一个 db.Model 对象关联的两个唯一字段的问题。
我的实现尝试通过实现创建 ParentEntity 的静态方法来解决此问题,并将其 key_name 属性分配给我的唯一值之一。在流程的第二步中,我创建一个子实体并将父实体分配给父参数。这两个步骤都是在数据库事务中执行的,因此我认为这将强制唯一性约束起作用,因为我的两个值都存储在两个单独模型中的两个单独的 key_name 字段中。
评论者指出,此解决方案不起作用,因为当您将父实体设置为子实体时, key_name 在整个模型中不再是唯一的,而是在父子条目中是唯一的。真糟糕...
我相信我可以通过改变这两个模型相互关联的方式来解决这个新问题。
首先,我创建一个父对象,如上所述。接下来,我创建一个子实体并将第二个唯一值分配给它的 key_name。不同之处在于第二个实体具有对父模型的引用属性。我的第一个实体分配给引用属性,但没有分配给父参数。这不会强制一对一引用,但它确实使我的两个值保持唯一,并且只要我可以从事务中控制插入过程,我就可以管理这些对象的一对一性质。
这个新的解决方案仍然存在问题。根据 GAE 数据存储文档,如果更新中的各个实体不属于同一实体组,则无法在一个事务中执行多个数据库更新。由于我不再将第一个实体作为第二个实体的父实体,因此它们不再属于同一实体组,并且无法插入到同一事务中。
我又回到了原点。我可以做什么来解决这个问题?具体来说,我可以做什么来强制执行与一个模型实体关联的两个唯一值。正如你所看到的,我愿意发挥一点创意。这可以做到吗?我知道这需要一个开箱即用的解决方案,但必须有办法。
以下是我上周发布的问题的原始代码。我添加了一些注释和代码更改来实现解决此问题的第二次尝试。
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, #My prt object was previously the parent of child
parentEnt=prt,
str1=string1,
str2_key=string2,
str3=string3,)
child.put()
return child
#This should give me an error, b/c these two entities are no longer in the same entity group. :(
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()
#This is no longer a "parent" but a reference
parentEnt = db.ReferenceProperty(reference_class=ParentEntity)
#pertinent data below
str3 = db.StringProperty()