Skip to content

Commit 639ceb2

Browse files
mathiasoseauvipy
authored andcommitted
Try to sort out migrations (#180)
v1.2.0 broke the upgrade path from v1.1.1 by renaming migration 0006. This meant it was possible to to a clean install of the package at v1.2.0, but not to upgrade from an existing v1.1.1 install that had applied the now nonexistent migration. This commit tries to resolve the situation so that there will be an upgrade path from v1.1.1 to v1.2.1, as well as from v1.2.0 to v1.2.1. The first step was to restore the v1.1.1 migrations and create a new migration 0007 so that the state of the schema was equivalent to v1.2.0. This results in two branches in the commit graph, which necessitates a merge migration ``` +--->0006+--->0007+--->0008+-+ | | | | 0005+-+ +-->0009_merge | | | | +--->0006+--->0007+----------+ ``` Finally, because both branches of the graph do the same operations, create a merge migration that replaces both branches andthe merge migration itself. Then fiddle a bit with the merge migration in an editor to remove the redundant operations, ensuring that `makemigrations --check --dry-run` continues to say `No changes detected`. We need to include 0005 in the squash because it is the root of the branches. The new migration is therefore 0005_squash. New installs of v1.2.1 and beyond will then only apply the merge migration, avoiding the two branches completely. Outcomes: - ✅ Can migrate a fresh install of this commit. ``` $ django-celery-beat git:(master) ✗ git checkout master Already on 'master' Your branch is ahead of 'origin/master' by 1 commit. (use "git push" to publish your local commits) $ django-celery-beat git:(master) ✗ rm t/db.sqlite3 rm: cannot remove 't/db.sqlite3': No such file or directory $ django-celery-beat git:(master) ✗ python manage.py migrate Operations to perform: Apply all migrations: admin, auth, contenttypes, django_celery_beat, sessions Running migrations: Applying contenttypes.0001_initial... OK Applying auth.0001_initial... OK Applying admin.0001_initial... OK Applying admin.0002_logentry_remove_auto_add... OK Applying admin.0003_logentry_add_action_flag_choices... 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 django_celery_beat.0001_initial... OK Applying django_celery_beat.0002_auto_20161118_0346... OK Applying django_celery_beat.0003_auto_20161209_0049... OK Applying django_celery_beat.0004_auto_20170221_0000... OK Applying django_celery_beat.0005_add_solarschedule_events_choices_squashed_0009_merge_20181012_1416... OK Applying sessions.0001_initial... OK $ django-celery-beat git:(master) ✗ python manage.py makemigrations --check --dry-run No changes detected ``` - ✅ Can migrate from the v1.1.1 state to this state. ``` $ django-celery-beat git:(master) ✗ git checkout v1.1.1 Note: checking out 'v1.1.1'. You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by performing another checkout. If you want to create a new branch to retain commits you create, you may do so (now or later) by using -b with the checkout command again. Example: git checkout -b <new-branch-name> HEAD is now at 60b7fc6 Bump version: 1.1.0 → 1.1.1 $ django-celery-beat git:(60b7fc6) ✗ rm t/db.sqlite3 $ django-celery-beat git:(60b7fc6) ✗ python manage.py migrate Operations to perform: Apply all migrations: admin, auth, contenttypes, django_celery_beat, sessions Running migrations: Applying contenttypes.0001_initial... OK Applying auth.0001_initial... OK Applying admin.0001_initial... OK Applying admin.0002_logentry_remove_auto_add... OK Applying admin.0003_logentry_add_action_flag_choices... 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 django_celery_beat.0001_initial... OK Applying django_celery_beat.0002_auto_20161118_0346... OK Applying django_celery_beat.0003_auto_20161209_0049... OK Applying django_celery_beat.0004_auto_20170221_0000... OK Applying django_celery_beat.0005_add_solarschedule_events_choices... OK Applying django_celery_beat.0006_auto_20180210_1226... OK Applying sessions.0001_initial... OK $ django-celery-beat git:(60b7fc6) ✗ git checkout master Previous HEAD position was 60b7fc6 Bump version: 1.1.0 → 1.1.1 Switched to branch 'master' Your branch is ahead of 'origin/master' by 1 commit. (use "git push" to publish your local commits) $ django-celery-beat git:(master) ✗ python manage.py migrate Operations to perform: Apply all migrations: admin, auth, contenttypes, django_celery_beat, sessions Running migrations: Applying django_celery_beat.0006_auto_20180322_0932... OK Applying django_celery_beat.0007_auto_20180521_0826... OK Applying django_celery_beat.0008_auto_20180914_1922... OK Applying django_celery_beat.0007_auto_20181012_1414... OK Applying django_celery_beat.0009_merge_20181012_1416... OK $ django-celery-beat git:(master) ✗ python manage.py makemigrations --check --dry-run No changes detected ``` - ✅ Can migrate from the v1.2.0 state to this state. ``` $ django-celery-beat git:(master) ✗ git checkout v1.2.0 Note: checking out 'v1.2.0'. You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by performing another checkout. If you want to create a new branch to retain commits you create, you may do so (now or later) by using -b with the checkout command again. Example: git checkout -b <new-branch-name> HEAD is now at f927cde Bump version: 1.1.1 → 1.2.0 $ django-celery-beat git:(f927cde) ✗ rm t/db.sqlite3 $ django-celery-beat git:(f927cde) ✗ python manage.py migrate Operations to perform: Apply all migrations: admin, auth, contenttypes, django_celery_beat, sessions Running migrations: Applying contenttypes.0001_initial... OK Applying auth.0001_initial... OK Applying admin.0001_initial... OK Applying admin.0002_logentry_remove_auto_add... OK Applying admin.0003_logentry_add_action_flag_choices... 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 django_celery_beat.0001_initial... OK Applying django_celery_beat.0002_auto_20161118_0346... OK Applying django_celery_beat.0003_auto_20161209_0049... OK Applying django_celery_beat.0004_auto_20170221_0000... OK Applying django_celery_beat.0005_add_solarschedule_events_choices... OK Applying django_celery_beat.0006_auto_20180322_0932... OK Applying django_celery_beat.0007_auto_20180521_0826... OK Applying django_celery_beat.0008_auto_20180914_1922... OK Applying sessions.0001_initial... OK $ django-celery-beat git:(f927cde) ✗ git checkout master Previous HEAD position was f927cde Bump version: 1.1.1 → 1.2.0 Switched to branch 'master' Your branch is ahead of 'origin/master' by 1 commit. (use "git push" to publish your local commits) $ django-celery-beat git:(master) ✗ python manage.py migrate Operations to perform: Apply all migrations: admin, auth, contenttypes, django_celery_beat, sessions Running migrations: Applying django_celery_beat.0006_auto_20180210_1226... OK Applying django_celery_beat.0007_auto_20181012_1414... OK Applying django_celery_beat.0009_merge_20181012_1416... OK $ django-celery-beat git:(master) ✗ python manage.py makemigrations --check --dry-run No changes detected ```
1 parent 2aee95e commit 639ceb2

File tree

4 files changed

+225
-0
lines changed

4 files changed

+225
-0
lines changed
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
# Generated by Django 2.1.2 on 2018-10-12 14:18
2+
from __future__ import absolute_import, unicode_literals
3+
4+
from django.db import migrations, models
5+
import django_celery_beat.validators
6+
import timezone_field.fields
7+
8+
9+
class Migration(migrations.Migration):
10+
replaces = [
11+
('django_celery_beat', '0005_add_solarschedule_events_choices'),
12+
('django_celery_beat', '0006_auto_20180322_0932'),
13+
('django_celery_beat', '0007_auto_20180521_0826'),
14+
('django_celery_beat', '0008_auto_20180914_1922'),
15+
('django_celery_beat', '0006_auto_20180210_1226'),
16+
('django_celery_beat', '0007_auto_20181012_1414'),
17+
('django_celery_beat', '0009_merge_20181012_1416')]
18+
19+
dependencies = [
20+
('django_celery_beat', '0004_auto_20170221_0000'),
21+
]
22+
23+
operations = [
24+
migrations.AlterField(
25+
model_name='solarschedule',
26+
name='event',
27+
field=models.CharField(
28+
choices=[('dawn_astronomical', 'dawn_astronomical'),
29+
('dawn_civil', 'dawn_civil'),
30+
('dawn_nautical', 'dawn_nautical'),
31+
('dusk_astronomical', 'dusk_astronomical'),
32+
('dusk_civil', 'dusk_civil'),
33+
('dusk_nautical', 'dusk_nautical'),
34+
('solar_noon', 'solar_noon'), ('sunrise', 'sunrise'),
35+
('sunset', 'sunset')], max_length=24,
36+
verbose_name='event'),
37+
),
38+
migrations.AlterModelOptions(
39+
name='crontabschedule',
40+
options={
41+
'ordering': ['month_of_year', 'day_of_month', 'day_of_week',
42+
'hour', 'minute', 'timezone'],
43+
'verbose_name': 'crontab', 'verbose_name_plural': 'crontabs'},
44+
),
45+
migrations.AlterModelOptions(
46+
name='crontabschedule',
47+
options={
48+
'ordering': ['month_of_year', 'day_of_month', 'day_of_week',
49+
'hour', 'minute', 'timezone'],
50+
'verbose_name': 'crontab', 'verbose_name_plural': 'crontabs'},
51+
),
52+
migrations.AddField(
53+
model_name='crontabschedule',
54+
name='timezone',
55+
field=timezone_field.fields.TimeZoneField(default='UTC'),
56+
),
57+
migrations.AddField(
58+
model_name='periodictask',
59+
name='one_off',
60+
field=models.BooleanField(default=False,
61+
verbose_name='one-off task'),
62+
),
63+
migrations.AddField(
64+
model_name='periodictask',
65+
name='start_time',
66+
field=models.DateTimeField(blank=True, null=True,
67+
verbose_name='start_time'),
68+
),
69+
migrations.AlterField(
70+
model_name='crontabschedule',
71+
name='day_of_month',
72+
field=models.CharField(default='*', max_length=124, validators=[
73+
django_celery_beat.validators.day_of_month_validator],
74+
verbose_name='day of month'),
75+
),
76+
migrations.AlterField(
77+
model_name='crontabschedule',
78+
name='day_of_week',
79+
field=models.CharField(default='*', max_length=64, validators=[
80+
django_celery_beat.validators.day_of_week_validator],
81+
verbose_name='day of week'),
82+
),
83+
migrations.AlterField(
84+
model_name='crontabschedule',
85+
name='hour',
86+
field=models.CharField(default='*', max_length=96, validators=[
87+
django_celery_beat.validators.hour_validator],
88+
verbose_name='hour'),
89+
),
90+
migrations.AlterField(
91+
model_name='crontabschedule',
92+
name='minute',
93+
field=models.CharField(default='*', max_length=240, validators=[
94+
django_celery_beat.validators.minute_validator],
95+
verbose_name='minute'),
96+
),
97+
migrations.AlterField(
98+
model_name='crontabschedule',
99+
name='month_of_year',
100+
field=models.CharField(default='*', max_length=64, validators=[
101+
django_celery_beat.validators.month_of_year_validator],
102+
verbose_name='month of year'),
103+
),
104+
]
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Generated by Django 2.0.1 on 2018-02-10 12:26
2+
from __future__ import absolute_import, unicode_literals
3+
4+
from django.db import migrations, models
5+
6+
7+
class Migration(migrations.Migration):
8+
9+
dependencies = [
10+
('django_celery_beat', '0005_add_solarschedule_events_choices'),
11+
]
12+
13+
operations = [
14+
migrations.AlterField(
15+
model_name='crontabschedule',
16+
name='day_of_month',
17+
field=models.CharField(default='*', max_length=124,
18+
verbose_name='day of month'),
19+
),
20+
migrations.AlterField(
21+
model_name='crontabschedule',
22+
name='hour',
23+
field=models.CharField(default='*', max_length=96,
24+
verbose_name='hour'),
25+
),
26+
migrations.AlterField(
27+
model_name='crontabschedule',
28+
name='minute',
29+
field=models.CharField(default='*', max_length=240,
30+
verbose_name='minute'),
31+
),
32+
]
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# Generated by Django 2.1.2 on 2018-10-12 14:14
2+
from __future__ import absolute_import, unicode_literals
3+
4+
from django.db import migrations, models
5+
import django_celery_beat.validators
6+
import timezone_field.fields
7+
8+
9+
class Migration(migrations.Migration):
10+
dependencies = [
11+
('django_celery_beat', '0006_auto_20180210_1226'),
12+
]
13+
14+
operations = [
15+
migrations.AlterModelOptions(
16+
name='crontabschedule',
17+
options={
18+
'ordering': ['month_of_year', 'day_of_month', 'day_of_week',
19+
'hour', 'minute', 'timezone'],
20+
'verbose_name': 'crontab', 'verbose_name_plural': 'crontabs'},
21+
),
22+
migrations.AddField(
23+
model_name='crontabschedule',
24+
name='timezone',
25+
field=timezone_field.fields.TimeZoneField(default='UTC'),
26+
),
27+
migrations.AddField(
28+
model_name='periodictask',
29+
name='one_off',
30+
field=models.BooleanField(default=False,
31+
verbose_name='one-off task'),
32+
),
33+
migrations.AddField(
34+
model_name='periodictask',
35+
name='start_time',
36+
field=models.DateTimeField(blank=True, null=True,
37+
verbose_name='start_time'),
38+
),
39+
migrations.AlterField(
40+
model_name='crontabschedule',
41+
name='day_of_month',
42+
field=models.CharField(default='*', max_length=124, validators=[
43+
django_celery_beat.validators.day_of_month_validator],
44+
verbose_name='day of month'),
45+
),
46+
migrations.AlterField(
47+
model_name='crontabschedule',
48+
name='day_of_week',
49+
field=models.CharField(default='*', max_length=64, validators=[
50+
django_celery_beat.validators.day_of_week_validator],
51+
verbose_name='day of week'),
52+
),
53+
migrations.AlterField(
54+
model_name='crontabschedule',
55+
name='hour',
56+
field=models.CharField(default='*', max_length=96, validators=[
57+
django_celery_beat.validators.hour_validator],
58+
verbose_name='hour'),
59+
),
60+
migrations.AlterField(
61+
model_name='crontabschedule',
62+
name='minute',
63+
field=models.CharField(default='*', max_length=240, validators=[
64+
django_celery_beat.validators.minute_validator],
65+
verbose_name='minute'),
66+
),
67+
migrations.AlterField(
68+
model_name='crontabschedule',
69+
name='month_of_year',
70+
field=models.CharField(default='*', max_length=64, validators=[
71+
django_celery_beat.validators.month_of_year_validator],
72+
verbose_name='month of year'),
73+
),
74+
]
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Generated by Django 2.1.2 on 2018-10-12 14:16
2+
from __future__ import absolute_import, unicode_literals
3+
4+
from django.db import migrations
5+
6+
7+
class Migration(migrations.Migration):
8+
9+
dependencies = [
10+
('django_celery_beat', '0007_auto_20181012_1414'),
11+
('django_celery_beat', '0008_auto_20180914_1922'),
12+
]
13+
14+
operations = [
15+
]

0 commit comments

Comments
 (0)