I have two apps in my Django project. Foo and Bar. I have made some migrations for Bar and then decided to unapply them. And so I have 6 migrations for Bar and 10 migrations for Foo. ./manage.py migrate Bar 0004 - I'm rolling back to a migration #4. But it unapplies not only last two migrations in Bar, it unapplies also three last migrations in Foo. I noticed that those migrations have Bar 0004 migration in dependencies (except the last one):
dependencies = [
('bar', '0004_merge'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('foo', '0008_auto_20150507_1303'),
]
Okay, they think they are dependent on Bar 0004 migration, but I don't unapply it. I unapply only 0005 and 0006. Why three last Foo migrations also get unapplied? What could be the reason behind such behaviour?
Related
I have some database migrations, some are structural migrations some are data migrations
eg.
0001_initial.py
0002_import_data.py
0003_add_field.py
0004_import_more_data.py
I would like to skip those data migrations (0002 and 0004) as I don't want to spend the effort to fake the source for those data migrations but still run 0001 and 0003 when running python manage.py test
Is it possible?
You can edit the data migration files and conditionally set operations to an empty list, or remove just the operations you want to skip. You then need to detect when you are running under a test, this can be done by having a separate settings file or setting an environment variable
class Migration(migrations.Migration):
dependencies = [
('app', '0001_initial'),
]
operations = [
migrations.RunPython(import_function),
]
if settings.TEST: # if os.environ('SKIP_DATA_MIGRATIONS') == 'true':
operations = []
With Django 1.11.22 I'm trying to run migrations
python manage.py migrate
django.db.migrations.exceptions.InconsistentMigrationHistory: Migration base.0036_auto_20190227_1226 is applied before its dependency base.0027_auto_20170801_1228_squashed_0037_auto_20190222_1347 on database 'default'.
My first try to solve this was
sudo -u postgres psql -d albatros -c \
"DELETE FROM django_migrations WHERE name = '0036_auto_20190227_1226' AND app = 'base'"
In the hope of deleting the migration from the migration table would fix it. Unfortunately I'm now getting:
CommandError: Conflicting migrations detected; multiple leaf nodes in the migration graph: (0037_auto_20190222_1347, 0036_auto_20190227_1226 in base).
To fix them run 'python manage.py makemigrations --merge'
When tryin makemigrations --merge it does not find any migrations to merge. This is what showmigrations looks like:
./manage.py showmigrations base
base
[X] 24_initial
[X] 24_to_26
[X] 26_to_27
[X] 0027_auto_20170801_1228
[X] 0028_resourcebase_is_approved
[X] 0029_auto_20171114_0341
[X] 0030_auto_20180309_0833
[X] 0031_auto_20180309_0837
[X] 0032_auto_20180329_1844
[X] 0033_auto_20180330_0951
[X] 0034_auto_20180606_1543
[X] 0035_resourcebase_dirty_state
[ ] 0036_auto_20190227_1226
[ ] 0036_auto_20190129_1433
[ ] 0037_auto_20190222_1347
Can one say how to correctly apply the migrations and solve the multiple leaf nodes error?
In this 2 migration files (0037_auto_20190222_1347, 0036_auto_20190227_1226) you have same dependencies, check them. They seems like a list with tuple in it
dependencies = [
('round', '0008_auto_20200116_0752'),
]
You need to manually write "0036_auto_20190227_1226" into 0037_auto_20190222_1347 file dependencies variable.
each django migration contains a dependency referring to the migration before it, as if it were a breadcrumb, this is controlled through the files that are in the migrations folder as well as through the database, in the django_migrations table. Each migration file has a line something like this:
dependencies = [
('round', '0008_auto_20200116_0752'),
]
where the second parameter of the tuple must be exactly the name that must be in the database in the django_migrations table. That way the tree cannot have loose nodes, make sure your database in the django_migrations table is consistent with the migration sequence of each file through the dependencies:
dependencies = [
('round', '0008_auto_20200116_0752'),
]
An alternative to resolve this would be to use django-migration-fixer
Fixing migrations on your dev branch can be done using
$ git checkout [dev-branch]
$ git merge [main/master]
Follow the installation instructions here
Run
$ python manage.py makemigrations --fix -b [main/master]
commit the changes and push to the remote branch
$ git add .
$ git commit -am ...
$ git push ...
You can merge your migration and do migrate
(venv)yourprj$python manage.py makemigrations --merge
(venv)yourprj$python manage.py migrate
I have app(example) and there is only one migrations. And I have changed it and I want to unapply and apply it again. If there are many migrations and I want to unapply 0002 migrations, I would use:
django-admin migrate example 0001
but question is how can I unapply first migration?
You can pass 'zero' to unapply all of the migrations for an app.
./manage.py migrate example zero
You can see the docs here https://docs.djangoproject.com/en/2.0/ref/django-admin/#migrate
use zero
django-admin migrate example zero
in the doc
Use the name zero to unapply all migrations for an app.
You can do it by
./manage.py migrate <app> zero
I have a django app called Locations and in its models.py there are 2 models:
class City(models.Model):
...
class Country(models.Model):
...
I did python manage.py schemamigration Locations --initial and then python manage.py migrate Locations. Everything worked fine.
Then I added 2 fields to City and did python manage.py schemamigration Locations --auto and it said:
Deleted field cover_image on Locations.Country
Added field lng on Locations.City
Added field ltd on Locations.City
Created 0003_auto__del_field_country_cover_image__add_field_city_lng__add_field_cit.py. You can now apply this migration with: ./manage.py migrate Locations
Then when I did python manage.py migrate Locations, I got:
Running migrations for Locations:
- Migrating forwards to 0003_auto__del_field_country_cover_image__add_field_city_lng__add_field_cit.
> Locations:0001_initial
FATAL ERROR - The following SQL query failed: CREATE TABLE "Locations_country" ("id" serial NOT NULL PRIMARY KEY, "name" varchar(100) NOT NULL UNIQUE, "slug" varchar(50) NOT NULL, "image" varchar(100) NOT NULL, "flag" varchar(100) NOT NULL)
The error was: relation "Locations_country" already exists
Error in migration: Locations:0001_initial
DatabaseError: relation "Locations_country" already exists
I always keep getting this error. Am I doing something wrong?
Then I did python manage.py migrate Locations 0003 --fake and this was the output:
- Soft matched migration 0003 to 0003_auto__del_field_country_cover_image__add_field_city_lng__add_field_cit.
Running migrations for Locations:
- Migrating forwards to 0003_auto__del_field_country_cover_image__add_field_city_lng__add_field_cit.
> Locations:0001_initial
(faked)
> Locations:0002_auto__add_field_city_lng__add_field_city_ltd
(faked)
> Locations:0002_auto__add_location__add_field_country_cover_image
(faked)
> Locations:0003_auto__del_field_country_cover_image__add_field_city_lng__add_field_cit
(faked)
Now when I do python manage.py migrate Locations it says:
Running migrations for Locations:
- Nothing to migrate.
- Loading initial data for Locations.
Installed 0 object(s) from 0 fixture(s)
And those 2 fields have not been added. Whats going on? Whats the correct way to add/delete fields?
I have read the basic South documentation, please point to me if I have missed out something.
Thanks.
Delete 0002 and 0003 migrations files. And then roll back to 0001 by doing:
python manage.py migrate Locations 0001 --fake --delete-ghost-migrations
After that run schemamigration and migrate normally.
(During discussion with OP it was first cleared that 0002 and 0003 was never reflected to database, so it is no harm to delete those migration files from disk)
In Django-South:
I changed I've run the initial migration successfully for myapp but for some reason, after I've made a change to my model and go to
./manage.py schemamigration myapp --auto
./manage.py migrate myapp
And I get a lot of traceback which ends in:
(1050, "Table 'my_table' already exists")
After much googling, I found and tried this:
./manage.py migrate myapp --fake
And then I proceed to migrate it, to no avail; same error.
Any suggestions?
I just got this same error, and found this question by search.
My problem was that my second migration I'd created using the --initial flag, i.e.
$ ./manage.py startapp foo
$ ./manage.py schemamigration --initial foo
$ ./manage.py migrate foo
... make some changes to foo ...
$ ./manage.py schemamigration --initial foo
(oops!)
$ ./manage.py migrate foo
... and I get the error, and the migration fails because in the second migration, South is trying to create a table its already created.
Solution
In my migrations folder:
$ ls foo/migrations
0001_initial.py 0002_initial.py
remove that second migration and re-export the second migration with the correct --auto flag:
$ rm foo/migrations/0002_initial.py
$ ./manage.py schemamigration --auto foo
$ ./manage.py migrate foo
Success!
There may be other things that cause this error, but that was my bad!
Is it an existing app?
In that case you will need to convert it in addition to the fake bit.
There are good docs here on converting an existing app.
Although they are quite tricky to find if you don't know where they are already ( ;
For converting, after adding south to your installed apps:
./manage.py syncdb
./manage.py convert_to_south myapp
./manage.py migrate myapp 0001 --fake
this problem actually happens if one of the cases:
1) You made "schemamigration app_name --initial" after one is "--auto"
2) You interrupted the last migration you have made.
To resolve such problem you apply the following:
1) mark your last schema migration as fake.
python manage.py schemamigration app_name --fake
Note: Make sure that the schema of models is same as schema of tables in database.
2) apply the migration again by doing
python manage.py schemamigration app_Name --auto
python manage.py migrate app-Name
Note: sometimes you might add manually a specific field you already added using the following syntax.
python manage.py schemamigration app_name --add-field My_model.added_field
For more info. regarding south, you could check its documentation here.