Django 1.8: create initial migrations for an existing schema

I started a django 1.8 project that uses a migration system.
Somehow along the way, everything became messy, so I deleted the migration folders and the table from the database, and now I'm trying to restore them, without success.

I have three applications (3 models.py files), and the models reflect the tables EXACTLY!

The best approach I've found so far has been this:

  • Delete all migrations folders. Done!
  • Delete everything from the django_migrations table. Done!
  • Run python manage.py makemigrations --empty <app> for each application. Done!
  • Run python manage.py migrate --fake . Done! (although it only works if I run it after every makemigrations .

Now I add a new field, run the makemigrations command, and I get the following error:
django.db.utils.OperationalError: (1054, "Unknown column 'accounts_plan.max_item_size' in 'field list'")

I burn WATCH about it. How can h ** l initialize migration so that I can continue to work without interruption of migration every time?

Why is it so hard? Why is there no simple single-line line: initiate_migrations_from_schema ?

EDIT:
Now everything is becoming even more unpleasant. I truncated the django_migrations table and deleted the entire migrations folder.
Now I'm trying to run python manage.py migrate --fake-initial (something I found in the DEV docs), so that it configures all the internal Django applications (auth, session, etc.), and I get:
(1054, "Unknown column 'name' in 'django_content_type'") .
Now this “column” is not a real column. This is a @property defined in the Django contenttypes application. WHAT'S GOING ON HERE? Why does it identify the name property as a real column?

+57
django django-migrations
Apr 27 '15 at 5:44
source share
5 answers

Finally it worked, although I don’t know why, and I hope that it will work in the future. After numerous trials and going through the Django dev website ( link ).
Here are the steps (for those who are facing this problem):

  • Clear table django_migrations : delete from django_migrations;
  • For each application, delete its migrations folder: rm -rf <app>/migrations/
  • Reset migrations for embedded applications: python manage.py migrate --fake
  • For each application run: python manage.py makemigrations <app> . Take care of the dependencies (models with ForeignKey should run after their parent model).
  • Finally: python manage.py migrate --fake-initial

After that, I ran the last command without the --fake-initial flag to make sure.

Now everything works, and I can use the migration system normally.

I am sure that I am not the only one who faces this problem. It should be better documented and even simplified.

Update for Django 1.9 users:
I had this script again with Django 1.9.4, and step 5 failed.
All I had to do was replace --fake-initial with --fake to make it work.

+135
Apr 27 '15 at 14:26
source share

I came across this scenario, but I never had to abandon the database to solve this problem. Usually I delete the migration folder from the application and delete the migration entries from the database.

I would try running make migrations one application at a time. If any application relies on other tables, obviously they are added last.

Also I usually run python manage.py makemigrations , then just python manage.py migrate Even with the initial migration, it works fine with Django 1.7 and 1.8.

+2
Apr 27 '15 at 12:36
source share

django ..., 1.8, 1.9, ...

What you want to achieve is to crush existing migrations and use them to replace them.

How to do it right without using any command at release (a case without affecting the database and employees).

  • For each application, get rid of its migration folder: mv <app>/migrations/ <app>/migrationsOLD/

  • For each application: python manage.py makemigrations <app> .

  • Set up each new migration:

    • if you have a complex application or other applications and related models between them to avoid CircularDependencyError or ValueError: Unhandled pending operations for models :

      prepare the second empty migration to <app> 0002_initial2.py (add the dependency on app_other::0001_initial.py and <app> :: 0001_initial.py - all ForeignKey, M2M related to the models created at the migration stage 0001 in other applications)

      Everything should be in order - sometimes it requires more migrations. Take care of the dependencies attribute here in each migration.

    • take care of the initial values ​​- check all RunPython actions from migrationsOLD and copy the code to the new initial migration, if necessary.

    • (optional for --fake-initial ) Add initial=True to all new migration classes (0002 too, if added).

    • Add the replaces attribute to the new migration class. (e.g. native custom squashmigrations ). Put there all the old migrations from <app>
  • Check everything with makemigrations .

    approve "No changes detected"

  • Make sure migrate -l shows [x] everywhere

    claim like this:

    [X] 0001_initial

    [X] 0002_initial2 (102 compressed migrations)

Example:

For old:

 0001_initial.py 0002_auto.py ... 0103_auto.py 

prepare:

 0001_initial.py 0002_initial2.py (optional but sometimes required to satisfy dependency) 

and add to replaces for the latter (0002 here, maybe 0001):

 replaces = [(b'<app>', '0002_auto.py'), ..., (b'<app>', '0103_auto.py')] 

0001_initial.py should be called the same as the old one.

0002_initial2.py is new, but it replaces the old migrations, so Django will treat it as loaded.

+1
Apr 11 '17 at 7:33 on
source share

If you use routers, a problem may occur. Check the allow_migrate method if it is executed correctly in routers.py . Try setting the return value always to True and checking if it resolves the problem,

 def allow_migrate(self, db, app_label, model_name=None, **hints): return True 
0
Mar 22 '16 at 18:39
source share

If you still get this error when upgrading to Django 1.8, be sure to mock up and port individually for the third-party applications that your applications depend on.

-3
Nov 17 '15 at 15:57
source share



All Articles