Moving south for multi-tasking inheritance

I have two models previously inherited from models.Model, and now I have reorganized them to inherit from the same base model. For this, Django uses multi-table inheritance, and I'm trying to create a schema and data migration for this. The database has data that needs to be transferred.

I know that Django creates OneToOneField, but I do not understand how it affects existing elements in the database.

Before inheritance

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

After inheritance

 class Published(models.Model): published_on = models.DateTimeField() class BlogPost(Published): name = models.CharField() class AudioFile(Published): file = models.FileField() 

Migration

It was mainly a migration that was generated at startup:

./manage.py schemamigration app --auto .

Generated File:

 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) 

When I try to run it, it raises an IntegrityError:

 column "published_ptr_id" contains null values 
+6
source share
1 answer

You will need to break this down into three migrations:

  • Schema for creating the app_published table and adding two new publish_ptr columns. Add these new columns to null=True instead of 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) 
  • Datamigration to iterate over existing audio files and blogs. The code is basically:

     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() 
  • Schemamigration to remove id (and now unused) columns and published_on from older models. Also, change publish_ptr from null=True to primary_key=True on older models.

     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']) 
+10
source

Source: https://habr.com/ru/post/926351/


All Articles