Миграция на юг для наследования нескольких таблиц

У меня есть две модели, которые ранее унаследованы от models.Model, и теперь я их реорганизовал, чтобы унаследовать от той же базовой модели. Django использует для этого многотабличное наследование, и я пытаюсь создать для этого схему и миграцию данных. В базе данных есть данные, которые необходимо перенести.

Я знаю, что Django создает OneToOneField, но я не понимаю, как это влияет на существующие элементы в базе данных.

До наследования

class BlogPost(models.Model):
    name = models.CharField()
    published_on = models.DateTimeField()

class AudioFile(models.Model):
    file = models.FileField()
    published_on = models.DateTimeField()

После наследования

class Published(models.Model):
    published_on = models.DateTimeField()

class BlogPost(Published):
    name = models.CharField()

class AudioFile(Published):
    file = models.FileField()

Миграция

По сути, это была миграция, которая была сгенерирована при запуске:

./manage.py schemamigration app --auto.

Созданный файл:

class Migration(SchemaMigration):
    def forwards(self, orm):
        db.create_table('app_published', (
            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
            ('published_on', self.gf('django.db.models.fields.DateTimeField')()),
        ))
        db.send_create_signal('app', ['Published'])

        db.delete_column('app_blogpost', 'published_on')
        db.delete_column('app_blogpost', 'id')
        db.add_column('app_blogpost', 'published_ptr', self.gf('django.db.models.fields.related.OneToOneField')(default=None, to=orm['app.Published'], unique=True, primary_key=True), keep_default=False)

        db.delete_column('app_audiofile', 'published_on')
        db.delete_column('app_audiofile', 'id')
        db.add_column('app_audiofile', 'published_ptr', self.gf('django.db.models.fields.related.OneToOneField')(default=None, to=orm['app.Published'], unique=True, primary_key=True), keep_default=False)

Когда я пытаюсь запустить его, возникает ошибка IntegrityError:

column "published_ptr_id" contains null values

person Community    schedule 26.09.2012    source источник


Ответы (1)


Вам нужно будет разбить это на три миграции:

  1. Схема миграции для создания таблицы app_published и добавления двух новых столбцов published_ptr. Добавьте эти новые столбцы с null=True вместо primary_key=True:

    db.create_table('app_published', (
        ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
        ('published_on', self.gf('django.db.models.fields.DateTimeField')()),
    ))
    db.add_column('app_blogpost', 'published_ptr', self.gf('django.db.models.fields.related.OneToOneField')(default=None, to=orm['app.Published'], null=True), keep_default=False)
    db.add_column('app_audiofile', 'published_ptr', self.gf('django.db.models.fields.related.OneToOneField')(default=None, to=orm['app.Published'], null=True), keep_default=False)
    
  2. Перенос данных для перебора существующих аудиофайлов и сообщений в блогах. Код в основном:

    for blogpost in orm.BlogPost.objects.all():
        published = orm.Published.objects.create(published_on=blogpost.published_on)
        blogpost.published_ptr = published
        blogpost.save()
    
    for audiofile in orm.AudioFile.objects.all():
        published = orm.Published.objects.create(published_on=audiofile.published_on)
        audiofile.published_ptr = published
        audiofile.save()
    
  3. Схема миграции для удаления (теперь неиспользуемых) столбцов id и published_on из ваших старых моделей. Кроме того, в старых моделях измените значение published_ptr с null=True на primary_key=True.

    db.delete_column('app_blogpost', 'published_on')
    db.delete_column('app_blogpost', 'id')
    db.delete_column('app_audiofile', 'published_on')
    db.delete_column('app_audiofile', 'id')
    
    db.alter_column('app_blogpost', 'published_ptr', self.gf('django.db.models.fields.related.OneToOneField')(default=None, to=orm['app.Published'], null=False))
    db.alter_column('app_audiofile', 'published_ptr', self.gf('django.db.models.fields.related.OneToOneField')(default=None, to=orm['app.Published'], null=False))
    
    db.create_index('app_blogpost', ['published_ptr'], unique=True)
    db.create_index('app_audiofile', ['published_ptr'], unique=True)
    db.create_primary_key('app_blogpost', ['published_ptr'])
    db.create_primary_key('app_audiofile', ['published_ptr'])
    
person dokkaebi    schedule 26.09.2012