0

I have two development machines for django projects - tower and laptop. I use a private git repo to keep the projects synchronized. I work on tower for awhile, commit the changes to my git repo (including the database), then do a git pull origin master, and git reset --hard origin/master, and then I work on the laptop when I travel.

I seem to have made a mistake somewhere, as when I updated laptop as above, I have an error in my migrations. On tower, all the migrations are current and applied. On laptop, I have several migrations that cannot be applied.

 [X] 0044_remove_document_rotation
 [ ] 0041_remove_collectiondocument_position
 [ ] 0045_merge_20191023_1922
 [X] 0045_auto_20191121_1536
 [ ] 0046_merge_20200213_1523
 [X] 0046_auto_20200213_1541
 [ ] 0047_merge_20200213_1546

These migrations are all checked on tower. I get an error when I try to migrate on laptop:

  Applying memorabilia.0041_remove_collectiondocument_position...Traceback (most recent call last):
  File "./manage.py", line 15, in <module>
    execute_from_command_line(sys.argv)
  File "/home/mark/.virtualenvs/memorabilia-JSON/lib/python3.6/site-packages/django/core/management/__init__.py", line 401, in execute_from_command_line
    utility.execute()
  File "/home/mark/.virtualenvs/memorabilia-JSON/lib/python3.6/site-packages/django/core/management/__init__.py", line 395, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/home/mark/.virtualenvs/memorabilia-JSON/lib/python3.6/site-packages/django/core/management/base.py", line 328, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/home/mark/.virtualenvs/memorabilia-JSON/lib/python3.6/site-packages/django/core/management/base.py", line 369, in execute
    output = self.handle(*args, **options)
  File "/home/mark/.virtualenvs/memorabilia-JSON/lib/python3.6/site-packages/django/core/management/base.py", line 83, in wrapped
    res = handle_func(*args, **kwargs)
  File "/home/mark/.virtualenvs/memorabilia-JSON/lib/python3.6/site-packages/django/core/management/commands/migrate.py", line 233, in handle
    fake_initial=fake_initial,
  File "/home/mark/.virtualenvs/memorabilia-JSON/lib/python3.6/site-packages/django/db/migrations/executor.py", line 117, in migrate
    state = self._migrate_all_forwards(state, plan, full_plan, fake=fake, fake_initial=fake_initial)
  File "/home/mark/.virtualenvs/memorabilia-JSON/lib/python3.6/site-packages/django/db/migrations/executor.py", line 147, in _migrate_all_forwards
    state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
  File "/home/mark/.virtualenvs/memorabilia-JSON/lib/python3.6/site-packages/django/db/migrations/executor.py", line 245, in apply_migration
    state = migration.apply(state, schema_editor)
  File "/home/mark/.virtualenvs/memorabilia-JSON/lib/python3.6/site-packages/django/db/migrations/migration.py", line 114, in apply
    operation.state_forwards(self.app_label, project_state)
  File "/home/mark/.virtualenvs/memorabilia-JSON/lib/python3.6/site-packages/django/db/migrations/operations/fields.py", line 172, in state_forwards
    delay = not old_field.is_relation
AttributeError: 'NoneType' object has no attribute 'is_relation'

The project runs on both tower and laptop.

How do I get these migrations applied on laptop, or remove the ones that are causing the issues?

Zoe
  • 27,060
  • 21
  • 118
  • 148
user1045680
  • 815
  • 2
  • 9
  • 19

2 Answers2

1

Have you tried to take the migrations on your laptop? This marks migrations as applied so you won't run into trouble with them again.

Fake a single migration file: python manage.py migrate --fake <APP_NAME> <MIGRATION>

Fake all migrations for an app: python manage.py migrate --fake <APP_NAME>

Fake all migrations: python manage.py migrate --fake

Zoe
  • 27,060
  • 21
  • 118
  • 148
LetItBeAndre
  • 151
  • 1
  • 10
  • First, I am not sure what you mean in your question. My current situation is that uploaded the working app to git with the corresponding mysql backup from tower. I downloaded from git the working app and mysql backup from git to laptop, which overwrote the old code on laptop and the old db on laptop. Laptop and tower should be the same now, except the migrations fail on laptop and not on tower. Second, how will faking migrations help in this situation? – user1045680 Feb 14 '20 at 01:07
  • Ok didn't got the problem right. Can you somehow verify that the DB on your laptop is the same as the one on the tower? Since Django stores information about the migrations in the DB, there shouldn't be any difference. Anyways with fake migrations you can make Django pretend it migrated the migrations without actually running migrate. When I got you right your app is running and everything seems fine. If so you can just give fake migrations a try ;) – LetItBeAndre Feb 14 '20 at 08:03
0

When I run into problems with syncing like this, as a last resort, I often remove the migrations and begin from scratch. To do this:

  1. Create a backup of all your migrations in your migrations folder (eg. 0001.iniital.py and 0002_auto_20191220_1357.py and others like it in myproject/myproject/myapp/migrations/), and then delete them.
  2. Go to your Django database and delete all the entries in django.migrations.
  3. Back up your tables and then delete them from your MySQL (or other) database.

The above will give you a completely clean slate.

Thereafter:

python manage.py makemigrations

Followed by:

python manage.py migrate

If your models are set up correctly this will recreate all your structure without errors. Finally, inspect the backed up tables and, where there are no differences, replace the existing tables. Where there are differences, make sure you make the necessary data structure modifications before syncing.

I find it's often faster to do this method when dealing with a manageable database size, than to figure out the chain of what went wrong with the migrations.

Hayden Eastwood
  • 928
  • 2
  • 10
  • 20
  • Hayden, I have done steps like this in the past, but I am not sure how it will impact the other computer. For example, the issue today is on laptop. So, if I clear out the migrations and create new ones as described above on laptop, then do some work on laptop, then push to the git repo. When I pull down from the git repo to tower, will I face the same issue with migrations, because they are not wildly different from what they were before? The migrations directory is in git. – user1045680 Feb 14 '20 at 00:59
  • A second question. Since I only push a working app to git, with the current mysql backup, do I really need to worry about the models and the db when I pull down the code base from git and the corresponding mysql backup? I would think I could just restore the db backup and replace the existing code base with the new stuff from git and it should all work. Am I missing something? – user1045680 Feb 14 '20 at 01:02
  • Since I often run into issues like you describe, I tend not to commit migration files to git and, instead, run migration as I need to on any computer that I sync to, thereby creating migrations on each folder that are distinct from each other. I've found that this often reduces the confusion that git and Django get themselves into. – Hayden Eastwood Feb 14 '20 at 08:28
  • In answer to your question: you shouldn't need to worry, I'm just being cautious! – Hayden Eastwood Feb 14 '20 at 08:37
  • @Hayden Eastwood commiting migration files is encouraged and mentioned as best practice in the Django documentation, see this post https://stackoverflow.com/a/28035246/12893650. I've been working on a couple of Django projects. All projects me and the others devs committed migrations to git went smoothly, the only project which caused the same trouble described here was one we ignored the migrations and worked with SQL dumps. – LetItBeAndre Feb 14 '20 at 10:03