How to ignore some migrations in production - django

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.

Related

Mark specific Django migrations as fake migrations during test DB setup

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 = []

Why django migrate command don't insert to django_migrations table

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.

Can´t create test database django

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/

what's the purpose of the dependencies array in django migration files

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

Why django creates new default permissions even with default_permissions=() in the Meta?

I setup some test app to check django's behaviour.
Makefile for testing:
clean:
rm db.sqlite3
mig_model:
python manage.py migrate flights 0001
mig_all:
python manage.py migrate
show1 show2:
python manage.py shell -c "from django.contrib.auth.models import Permission; print(list(Permission.objects.values_list('id', 'codename')))"
all: clean mig_model show1 mig_all show2
removing old db
migrating to the point when first own model is created
after migration default permissions should be created in post_migrate signal. But I specify in Model.Meta that no default permissions should be created
check all permissions - I can see that they were indeed generated
migrate everything else, which is just 1 more data-migration where I delete all permissions in the system
show all permissions again and I can see that old permission were deleted and new ones created after migration (they all have new ids)
models.py:
class Schedule(models.Model):
flight_day = models.DateField()
class Meta:
default_permissions = ()
permissions = ()
output of make all
.venv ❯ make all
rm db.sqlite3
python manage.py migrate flights 0001
Operations to perform:
Target specific migration: 0001_initial, from flights
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying auth.0010_alter_group_name_max_length... OK
Applying auth.0011_update_proxy_permissions... OK
Applying flights.0001_initial... OK
python manage.py shell -c "from django.contrib.auth.models import Permission; print(list(Permission.objects.values_list('id', 'codename')))"
[(5, 'add_group'), (6, 'change_group'), (7, 'delete_group'), (8, 'view_group'), (1, 'add_permission'), (2, 'change_permission'), (3, 'delete_permission'), (4, 'view_permission'), (9, 'add_user'), (10, 'change_user'), (11, 'delete_user'), (12, 'view_user'), (13, 'add_contenttype'), (14, 'change_contenttype'), (15, 'delete_contenttype'), (16, 'view_contenttype'), (17, 'add_schedule'), (18, 'change_schedule'), (19, 'delete_schedule'), (20, 'view_schedule'), (21, 'add_scheduleperf'), (22, 'change_scheduleperf'), (23, 'delete_scheduleperf'), (24, 'view_scheduleperf')]
python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, flights, sessions
Running migrations:
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying admin.0003_logentry_add_action_flag_choices... OK
Applying flights.0002_delete_perms...DELETE ALL (24, {'auth.Group_permissions': 0, 'auth.User_user_permissions': 0, 'auth.Permission': 24})
OK
Applying sessions.0001_initial... OK
python manage.py shell -c "from django.contrib.auth.models import Permission; print(list(Permission.objects.values_list('id', 'codename')))"
[(25, 'add_logentry'), (26, 'change_logentry'), (27, 'delete_logentry'), (28, 'view_logentry'), (33, 'add_group'), (34, 'change_group'), (35, 'delete_group'), (36, 'view_group'), (29, 'add_permission'), (30, 'change_permission'), (31, 'delete_permission'), (32, 'view_permission'), (37, 'add_user'), (38, 'change_user'), (39, 'delete_user'), (40, 'view_user'), (41, 'add_contenttype'), (42, 'change_contenttype'), (43, 'delete_contenttype'), (44, 'view_contenttype'), (49, 'add_schedule'), (50, 'change_schedule'), (51, 'delete_schedule'), (52, 'view_schedule'), (53, 'add_scheduleperf'), (54, 'change_scheduleperf'), (55, 'delete_scheduleperf'), (56, 'view_scheduleperf'), (45, 'add_session'), (46, 'change_session'), (47, 'delete_session'), (48, 'view_session')]
From Django Docs:
These permissions will be created when you run manage.py migrate; the
first time you run migrate after adding django.contrib.auth to
INSTALLED_APPS, the default permissions will be created for all
previously-installed models, as well as for any new models being
installed at that time. Afterward, it will create default permissions
for new models each time you run manage.py migrate (the function that
creates permissions is connected to the post_migrate signal).
The code:
default_permissions = ()
Does not prevent this from happening.
If I know more of what you're trying to do I might be able to help better.