Kit Fisto
Kit Fisto

Reputation: 4515

Django migrations: How to make existing model non-abstract?

I have two model classes Base and Derived (inherits from Base) and Base is abstract. Now I realize Base should be concrete. How can I create migrations that do the switch for me?

The main problem for me currently is the base_ptr_id column needed in the Derived table, which is a primary key. This column must be added and receive the correct values pointing to the corresponding rows in table Base. Currently I am doing these migration operations:

  1. create model base
  2. using RunSQL to copy the data from Derived table to Base table.
  3. add the OneToOneField base_ptr to Derived with primary_key=False
  4. using RunSQL to copy the ids into the base_ptr_id column
  5. removing the id column from Derived
  6. altering OneToOneField base_ptr to be a primary_key
  7. removing all other inherited fields from Derived

Currently the process fails at step 3. It looks like Django nevertheless creates a primary key column base_ptr_id, which fails because the existing rows would have the same default value.

So what can I do?

Upvotes: 2

Views: 418

Answers (1)

Kit Fisto
Kit Fisto

Reputation: 4515

Going further I came up with the following solution:

  1. create model base
  2. using RunSQL to copy the data from Derived table to Base table.
  3. add an integer field called base_ptr to Derived with primary_key=False and db_column='base_ptr_id'
  4. using RunSQL to copy the ids into the base_ptr_id column
  5. removing the id column from Derived
  6. altering base_ptr to be the required OneToOneField, which also implies to be a primary_key
  7. removing all other inherited fields from Derived

This way it seems to work.

Upvotes: 4

Related Questions