Вставка двух транзакций в транзакцию и получение ошибки «Невозможно работать с разными группами объектов в транзакции» Ошибка - PullRequest
3 голосов
/ 01 июля 2011

Моя конечная цель проста. Мне нужно иметь сущность, которая имеет два уникальных индексированных поля, которые могут работать как ключи. Если бы это была база данных SQL, в equivelant было бы два поля, которые определены как уникальные и независимые друг от друга. Я знаю, что эта функциональность напрямую невозможна для одного хранилища данных db.Model, поэтому мне пришлось создать сценарий Модель родитель-потомок, который имитирует это поведение.

Чтобы решить эту проблему, я создал две модели (ParentEntity и ChildEntity.) Модель ParentEntity представляет собой dummy db.Model, в которой хранятся два значения двух ключей, но только один из ключей. назначается параметру key_name модели # 1.

После создания родительской сущности я создаю вторую, дочернюю сущность, назначая второй ключ как имя_ключа и назначая родительскую сущность, которую я только что создал, дочерним сущностям parent параметр в конструкторе нового объекта ChildEntity.

Я предполагаю, что это будет держать эти объекты в одной и той же группе объектов, потому что это то, что подразумевает документация Google.

Я добавил метод вставки с именем InsertData в ParentEntity (который можно так же легко поместить в 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()

1 Ответ

2 голосов
/ 01 июля 2011

Я исправил эту проблему, но решение не связано с настройкой, упомянутой выше. Как я уже говорил ранее, мой настоящий класс содержит некоторый проверочный код в методе InsertData. Части логики валидации выполнялись в методе txn (). Я предположил, что это не будет проблемой, потому что все, что я проверяю, это проверка, чтобы убедиться, что в определенных параметрах есть текстовые значения и что один конкретный параметр имеет определенную длину.

После того, как я переместил проверку из метода txn (), операция вставки сработала без проблем. Отлично!

...