2013-11-19 3 views
0

Я только начал изучать структуру South, ожидая выпуска версии Django 1.7 и готовой продукции.Django/South: save() не работает, как ожидалось, при добавлении внешнего ключа в новую таблицу.

Я в этой начальной ситуации:

class TableA(models.Model): 
    CustomEntityA_ctype = models.ForeignKey(ContentType, related_name="tableB_related_name")  
    CustomEntityA_oid = models.PositiveIntegerField() 
    CustomEntityA  = generic.GenericForeignKey('CustomEntityA_ctype', 
                'CustomEntityA_oid') 

Я хотел бы эти схемы должны быть перемещены в нечто вроде этого

class TableB(models.Model): 
    CustomEntityB_ctype = models.ForeignKey(ContentType, related_name="tableB_related_name")  
    CustomEntityB_oid = models.PositiveIntegerField() 
    CustomEntityB  = generic.GenericForeignKey('CustomEntityB_ctype', 
                'CustomEntityB_oid') 

class TableA(models.Model): 
    tableB_entity = models.ForeignKey(TableB, 
             related_name='tableA_related_name', 
             null=False)   

Для того, чтобы получить это, я установки надлежащая начальная миграция, то моя промежуточная схема примерно такая:

class TableB(models.Model): 
    CustomEntityB_ctype = models.ForeignKey(ContentType, related_name="tableB_related_name")  
    CustomEntityB_oid = models.PositiveIntegerField() 
    CustomEntityB  = generic.GenericForeignKey('CustomEntityB_ctype', 
                'CustomEntityB_oid') 

class TableA(models.Model): 
    CustomEntityA_ctype = models.ForeignKey(ContentType, related_name="tableB_related_name")  
    CustomEntityA_oid = models.PositiveIntegerField() 
    CustomEntityA  = generic.GenericForeignKey('CustomEntityA_ctype', 
                'CustomEntityA_oid') 

    tableB_entity = models.ForeignKey(TableB, 
             related_name='tableA_related_name', 
             null=True)   

Что касается южного учебника, м пытается разделить миграцию на три части:

  1. Первая миграция --auto к этой промежуточной модели
  2. datamigration генерирования миграции Python скрипт
  3. Окончательный миграции --auto к конечной модели

Это содержание моих форвардов функционировать

def forwards(self, orm): 
    "Write your forwards methods here." 
    # Note: Don't use "from appname.models import ModelName". 
    # Use orm.ModelName to refer to models in this application, 
    # and orm['appname.ModelName'] for models in other applications. 
    for tableA_entity in orm.TableA.objects.all(): 
     ctype = tableA_entity.CustomEntityA_ctype 
     oid = tableA_entity.CustomEntityA_oid 

     tableB_entity = orm.TableB.objects.create(CustomEntityB_ctype=ctype, 
                CustomEntityB_oid=oid, 
               ) 

     print "created a tableB_entity", tableB_entity 
     tableA_entity.tableB_entity = tableB_entity 
     tableA_entity.save() 

     tableA_entity_FROMDB = orm.TableA.objects.all()[0] 

     print "tableA_entity_FROMDB.tableB_entity: ", tableA_entity_FROMDB.tableB_entity 

Когда я в voke шаг миграции, я получаю правильно созданный и напечатанный tableB_entity, но когда я печатаю результат запроса с двумя последними строками, я получаю пустой результат. В целом результат заключается в том, что функция save(), похоже, вообще не работает. Если я войду в оболочку manage.py и запрошу модели, то получаю ожидаемый результат в TableB, но пустой внешний ключ для соответствующего объекта в TableA.

Есть ли кто-нибудь, кто мог бы объяснить это мне?

Большое спасибо!

ответ

0

Единственный способ, с помощью которого я смог работать до сих пор, состоит в том, чтобы разделить схему и миграцию данных на два разных набора миграций.

  1. В первой схеме схема/данные мигрировали в сторону TableB с тремя дополнительными полями.
  2. Во втором я добавил внешний ключ в таблицу A и назначил объект TableB, созданный на предыдущем шаге, соответствующему объекту TableA.

Очевидно, что это не оптимально: если на первом этапе должна быть создана цель объекта отношения «много-к-одному», то во время второй миграции не было бы просто, чтобы сущность таблицы A указывала на вновь созданный элемент. Способом смягчения этого может быть создание временного обратного внешнего ключа из TableB в TableA, чтобы найти исходный объект TableA, который будет ссылаться, а затем удалять его при дальнейшей миграции.

Перед тем как принять это, я буду ждать еще некоторое время, чтобы позволить кому-то еще придумать «правильный» ответ :)

+0

Хорошо, я добавлю это в будущем. «Неправильное поведение» исходного сообщения, похоже, связано с конкретным бэкэнд, который я использовал, то есть sqlite3. При переходе на Postgres одни и те же сценарии миграции работали как обаяние. – Blazor