I have a django app with migrations. At one point in the past, I decided to delete a migration because it wasn't necessary, and I assumed it was safe to do that because I just updated the dependency in the next migration to be dependent on the previous migration:
migration 1
migration 2 <-- was dependent on 1, but deleted
migration 3 <-- was dependent on 2, but now depends on 1
but this was causing weird behavior in django where starting the server kept telling me I have unapplied migrations, and trying to run migrations would attempt to re-run migrations that were already applied. The other weirdness is, when I dropped the db and re-created, and ran migrations, it showed that all migrations ran successfully, but when I checked which migrations actually ran, it only shows 1 to have been applied:
running migrations:
Applying banner.0001_initial... OK
Applying banner.0003_auto_20180716_1309... OK
Applying banner.0004_auto_20180716_1520... OK
Applying banner.0005_auto_20180716_1529... OK
Applying banner.0006_auto_20180716_2225... OK
Applying banner.0007_auto_20180717_1939... OK
Applying banner.0008_auto_20180723_1409... OK
Applying banner.0009_auto_20180723_1420... OK
Applying banner.0010_auto_20180723_1423... OK
Applying banner.0011_auto_20180723_1424... OK
Applying banner.0012_auto_20180723_1427... OK
Applying banner.0013_auto_20180822_0057... OK
Applying banner.0014_auto_20180905_1435... OK
checking which ran:
# result of running `python manage.py migrate --list`
banner
[X] 0001_initial
[ ] 0003_auto_20180716_1309
[ ] 0004_auto_20180716_1520
[ ] 0005_auto_20180716_1529
[ ] 0006_auto_20180716_2225
[ ] 0007_auto_20180717_1939
[ ] 0008_auto_20180723_1409
[ ] 0009_auto_20180723_1420
[ ] 0010_auto_20180723_1423
[ ] 0011_auto_20180723_1424
[ ] 0012_auto_20180723_1427
[ ] 0013_auto_20180822_0057
[ ] 0014_auto_20180905_1435
I'm surprised that django doesn't show an error when the migrations are running, and instead just says 'OK', is this expected behavior? Also, what's the point of having the dependency array if it still relies on the files themselves?
UPDATE:
The migration that was deleted was #2; after the initial migration. It was called: 0002_migration_name.py
FWIW, these were the contents of the migration, which is why it was deleted:
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('banner', '0001_initial'),
]
operations = [
# migrations.AddField(
# model_name='banner',
# name='name1',
# field=models.IntegerField(default=1),
# preserve_default=True,
# ),
# migrations.AddField(
# model_name='banner',
# name='name2',
# field=models.CharField(max_length=255, null=True, verbose_name=b'UTM Value', blank=True),
# preserve_default=True,
# ),
]
interestingly, adding a new 0002 migration with an empty operations array, and updating dependencies so that 2 is dependent on 1, and 3 is depend on 2, fixes the issue
the way I checked which migrations ran was:
first, I ran this command: python manage.py migrate --list
Then, I checked the django_migrations table in the db, and it only had 1 record for the 'banner' migrations
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 = []
There was a change in the DB and the Model was modified. After running Makemigrations, I ran migrate.
The DB has been changed normally, but the history is not added to the django_migrations Table.
Because of this problem, a warning to continue to migrate appears even after migrating. And when I try to migrate again, the history is not added to the django_migrations table, so I try to change the DB as before, and this is of course an error.
This is migrations file.
class Migration(migrations.Migration):
dependencies = [
('common_py', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='customer_company',
name='del_date',
field=models.DateTimeField(default=None, null=True, verbose_name='삭제일'),
),
]
Run command "python manage.py migrate"
Result
(venv) PS D:\Projects\AFF\AFF> python manage.py migrate
Operations to perform:
Apply all migrations: auth, common_py, contenttypes, sessions
Running migrations:
Applying common_py.0002_customer_company_del_date... OK
Change Table Success
But didn't add history to "django_migrations" Table
Have you any idea? I Couldn't find any information about this. Thank you.
I turned off autocommit of mariadb. To use transaction in my Django program.
This is the reason of problem. I guess that the "python manage.py migration" command is not using transaction commit.
Solution.(Os windows)
open mariadb config file.
C:\Program Files\MariaDB 10.5\data\my.ini
Then add(or change) this line in
[mysqld]
autocommit=1
Restart pc or mariadb.
Complete.
I´m trying to test a django application, but when I run python manager.py test I got this error
django.db.utils.ProgrammingError: column deals_dealproposal.billing_branch_launcher_id does not exist
it´s occurs in
File "/migrations/0008_dynamicpackingtype.py", line 18, in run
for proposal in bulk_proposals:
In this point, billing_branch_launcher doesn't really exist, it´s create in migration 27
migrations.AddField(
model_name='dealproposal',
name='billing_branch_launcher',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, related_name='billing_branch_launcher', to='clients.CoffeeCompany'),
),
The migration 8 looks like this
class Migration(migrations.Migration):
dependencies = [
('coffeedeals', '0007_auto_20190315_1642'),
('schemas', '0003_dynamicpackingtype')
]
def run(app, schema_editor):
bulk_proposals = md.DealProposal.active.filter(
data__negotiation__packing='bulk',
data__negotiation__packing_type__isnull=False)
for proposal in bulk_proposals:
del proposal.data['negotiation']['packing_type']
proposal.save()
operations = [migrations.RunPython(run, atomic=True)]
How can I fix it?
I suggest install the python library
django-test-without-migrations
Then the migrations file errors don't affect to the tests.
pip install django-test-without-migrations
add it in INSTALLED_APPS (settings.py)
Then run :
python manage.py test --nomigrations
refer:https://pypi.org/project/django-test-without-migrations/
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
By mistake, now there is an inconsistency in the production and my local Django Migrations and the makemigrations command will generate correct migrations that when I locally run with an empty database. for example, this migration will generate:
class Migration(migrations.Migration):
dependencies = [
('campaign', '0208_auto_20190619_0929'),
]
operations = [
migrations.RemoveField(
model_name='bannerad',
name='average_price',
),
migrations.RemoveField(
model_name='bannerad',
name='click',
),
.... blah
migrations.AlterField(
model_name='bannerad',
name='size',
field=models.IntegerField(choices=[(0, '120x240'), (1, '120x600'), (2, '970x250'), (3, '160x600'), (4, '240x240'), (5, '300x100'), (6, '300x250'), (7, '468x60'), (8, '600x300'), (9, '728x90')]),
),
]
but in the production running the generated migrations already migrated (for example the Bannerad model in production database has not average_price)
and when I run the migrate command in production. How can I fix this issue?
You can mark a migration as already applied with the --fake parameter
E.g. to fake every unapplied migration up to and including 0209:
manage.py migrate --fake campaign 0209
Note that you can only fake the complete migrations, not individual operations within a migration.