django-postpone-index 0.0.3__tar.gz → 0.0.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {django_postpone_index-0.0.3/django_postpone_index.egg-info → django_postpone_index-0.0.4}/PKG-INFO +2 -1
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/README.md +1 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/dev/config/base_tests.py +28 -5
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/dev/config/settings.py +2 -0
- django_postpone_index-0.0.4/dev/test_explicit_constraint/tests.py +54 -0
- {django_postpone_index-0.0.3/dev/test_gis_index → django_postpone_index-0.0.4/dev/test_explicit_index}/tests.py +0 -1
- django_postpone_index-0.0.4/dev/test_fields/tests.py +43 -0
- django_postpone_index-0.0.4/dev/test_fields_rename/migrations/0001_initial.py +72 -0
- django_postpone_index-0.0.4/dev/test_fields_rename/migrations/0002_auto_20260204_0917.py +87 -0
- django_postpone_index-0.0.4/dev/test_fields_rename/models.py +81 -0
- {django_postpone_index-0.0.3/dev/test_fields → django_postpone_index-0.0.4/dev/test_fields_rename}/tests.py +0 -1
- {django_postpone_index-0.0.3/dev/test_explicit_constraint → django_postpone_index-0.0.4/dev/test_gis_index}/tests.py +0 -1
- {django_postpone_index-0.0.3/dev/test_explicit_index → django_postpone_index-0.0.4/dev/test_index_together}/tests.py +0 -1
- django_postpone_index-0.0.4/dev/test_model_rename/migrations/0001_initial.py +72 -0
- django_postpone_index-0.0.4/dev/test_model_rename/migrations/0002_auto_20260204_1037.py +38 -0
- django_postpone_index-0.0.4/dev/test_model_rename/models.py +60 -0
- django_postpone_index-0.0.4/dev/test_model_rename/tests.py +9 -0
- django_postpone_index-0.0.4/dev/test_unique_together/tests.py +72 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4/django_postpone_index.egg-info}/PKG-INFO +2 -1
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/django_postpone_index.egg-info/SOURCES.txt +12 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/postpone_index/_version.py +3 -3
- django_postpone_index-0.0.4/postpone_index/contrib/postgis/__init__.py +0 -0
- django_postpone_index-0.0.4/postpone_index/contrib/postgres/__init__.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/postpone_index/contrib/postgres/schema.py +32 -1
- django_postpone_index-0.0.4/postpone_index/management/__init__.py +0 -0
- django_postpone_index-0.0.4/postpone_index/management/commands/__init__.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/postpone_index/models.py +2 -1
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/postpone_index/utils.py +23 -5
- django_postpone_index-0.0.3/dev/test_index_together/tests.py +0 -10
- django_postpone_index-0.0.3/dev/test_unique_together/tests.py +0 -10
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/.github/workflows/ci.yml +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/.gitignore +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/dev/config/__init__.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/dev/config/urls.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/dev/config/utils.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/dev/config/wsgi.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/dev/manage.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/dev/test_explicit_constraint/__init__.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/dev/test_explicit_constraint/migrations/0001_initial.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/dev/test_explicit_constraint/migrations/0002_auto_20260130_1044.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/dev/test_explicit_constraint/migrations/0003_auto_20260130_1052.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/dev/test_explicit_constraint/migrations/__init__.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/dev/test_explicit_constraint/models.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/dev/test_explicit_index/__init__.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/dev/test_explicit_index/migrations/0001_initial.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/dev/test_explicit_index/migrations/0002_auto_20260130_1044.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/dev/test_explicit_index/migrations/0003_auto_20260130_1052.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/dev/test_explicit_index/migrations/__init__.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/dev/test_explicit_index/models.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/dev/test_fields/__init__.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/dev/test_fields/migrations/0001_initial.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/dev/test_fields/migrations/0002_auto_20260130_1258.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/dev/test_fields/migrations/0003_auto_20260130_1259.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/dev/test_fields/migrations/__init__.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/dev/test_fields/models.py +0 -0
- {django_postpone_index-0.0.3/dev/test_gis_index → django_postpone_index-0.0.4/dev/test_fields_rename}/__init__.py +0 -0
- {django_postpone_index-0.0.3/dev/test_gis_index → django_postpone_index-0.0.4/dev/test_fields_rename}/migrations/__init__.py +0 -0
- {django_postpone_index-0.0.3/dev/test_ignore_migration → django_postpone_index-0.0.4/dev/test_gis_index}/__init__.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/dev/test_gis_index/migrations/0001_initial.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/dev/test_gis_index/migrations/0002_gisindex1_mline.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/dev/test_gis_index/migrations/0003_auto_20260202_1156.py +0 -0
- {django_postpone_index-0.0.3/dev/test_ignore_migration → django_postpone_index-0.0.4/dev/test_gis_index}/migrations/__init__.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/dev/test_gis_index/models.py +0 -0
- {django_postpone_index-0.0.3/dev/test_index_together → django_postpone_index-0.0.4/dev/test_ignore_migration}/__init__.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/dev/test_ignore_migration/migrations/0001_initial.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/dev/test_ignore_migration/migrations/0002_auto_20260130_1044.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/dev/test_ignore_migration/migrations/0003_auto_20260130_1052.py +0 -0
- {django_postpone_index-0.0.3/dev/test_index_together → django_postpone_index-0.0.4/dev/test_ignore_migration}/migrations/__init__.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/dev/test_ignore_migration/models.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/dev/test_ignore_migration/tests.py +0 -0
- {django_postpone_index-0.0.3/dev/test_unique_together → django_postpone_index-0.0.4/dev/test_index_together}/__init__.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/dev/test_index_together/migrations/0001_initial.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/dev/test_index_together/migrations/0002_auto_20260130_1044.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/dev/test_index_together/migrations/0003_auto_20260130_1053.py +0 -0
- {django_postpone_index-0.0.3/dev/test_unique_together → django_postpone_index-0.0.4/dev/test_index_together}/migrations/__init__.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/dev/test_index_together/models.py +0 -0
- {django_postpone_index-0.0.3/postpone_index/contrib → django_postpone_index-0.0.4/dev/test_model_rename}/__init__.py +0 -0
- {django_postpone_index-0.0.3/postpone_index/contrib/postgis → django_postpone_index-0.0.4/dev/test_model_rename/migrations}/__init__.py +0 -0
- {django_postpone_index-0.0.3/postpone_index/contrib/postgres → django_postpone_index-0.0.4/dev/test_unique_together}/__init__.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/dev/test_unique_together/migrations/0001_initial.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/dev/test_unique_together/migrations/0002_auto_20260130_1044.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/dev/test_unique_together/migrations/0003_auto_20260130_1053.py +0 -0
- {django_postpone_index-0.0.3/postpone_index/management → django_postpone_index-0.0.4/dev/test_unique_together/migrations}/__init__.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/dev/test_unique_together/models.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/django_postpone_index.egg-info/dependency_links.txt +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/django_postpone_index.egg-info/requires.txt +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/django_postpone_index.egg-info/top_level.txt +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/postpone_index/__init__.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/postpone_index/admin.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/postpone_index/apps.py +0 -0
- {django_postpone_index-0.0.3/postpone_index/management/commands → django_postpone_index-0.0.4/postpone_index/contrib}/__init__.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/postpone_index/contrib/postgis/base.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/postpone_index/contrib/postgis/schema.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/postpone_index/contrib/postgres/base.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/postpone_index/management/commands/apply_postponed.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/postpone_index/migration_utils.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/postpone_index/sql/start.sql +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/postpone_index/testing_utils.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/pyproject.toml +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/setup.cfg +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/setup.py +0 -0
- {django_postpone_index-0.0.3 → django_postpone_index-0.0.4}/tox.ini +0 -0
{django_postpone_index-0.0.3/django_postpone_index.egg-info → django_postpone_index-0.0.4}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: django-postpone-index
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.4
|
|
4
4
|
Summary: Postpone index creation to provide Zero Downtime Migration feature
|
|
5
5
|
Home-page: https://github.com/nnseva/django-postpone-index
|
|
6
6
|
Author: Vsevolod Novikov
|
|
@@ -105,6 +105,7 @@ The following complex use cases are processed by the package.
|
|
|
105
105
|
- Back Migration. The both, forward and backward migrations are processed.
|
|
106
106
|
- Implicit index drop while removing the table. The Django doesn't issue a separate SQL to drop indexes of the dropped table.
|
|
107
107
|
- Implicit index drop while removing the field. The Django doesn't issue a separate SQL to drop indexes related to the dropped column.
|
|
108
|
+
- Rename field (column) name or model (table) name
|
|
108
109
|
|
|
109
110
|
## Using
|
|
110
111
|
|
|
@@ -56,6 +56,7 @@ The following complex use cases are processed by the package.
|
|
|
56
56
|
- Back Migration. The both, forward and backward migrations are processed.
|
|
57
57
|
- Implicit index drop while removing the table. The Django doesn't issue a separate SQL to drop indexes of the dropped table.
|
|
58
58
|
- Implicit index drop while removing the field. The Django doesn't issue a separate SQL to drop indexes related to the dropped column.
|
|
59
|
+
- Rename field (column) name or model (table) name
|
|
59
60
|
|
|
60
61
|
## Using
|
|
61
62
|
|
|
@@ -2,19 +2,37 @@
|
|
|
2
2
|
|
|
3
3
|
from django.apps import apps
|
|
4
4
|
from django.core.management import call_command
|
|
5
|
-
from django.db import DEFAULT_DB_ALIAS, connections
|
|
5
|
+
from django.db import DEFAULT_DB_ALIAS, connection, connections
|
|
6
|
+
from django.db.migrations.loader import MigrationLoader
|
|
6
7
|
from django.test import override_settings
|
|
7
8
|
|
|
8
9
|
from postpone_index import testing_utils
|
|
9
10
|
|
|
10
11
|
|
|
12
|
+
def _list_migrations(app_name):
|
|
13
|
+
"""Lists all module migrations"""
|
|
14
|
+
|
|
15
|
+
loader = MigrationLoader(connection, ignore_no_migrations=True)
|
|
16
|
+
graph = loader.graph
|
|
17
|
+
ret = []
|
|
18
|
+
for node in graph.leaf_nodes(app_name):
|
|
19
|
+
for plan_node in graph.forwards_plan(node):
|
|
20
|
+
if plan_node[0] == app_name:
|
|
21
|
+
ret.append(plan_node[1])
|
|
22
|
+
return ret
|
|
23
|
+
|
|
24
|
+
|
|
11
25
|
class TestCase(testing_utils.TestCase):
|
|
12
26
|
__doc__ = __doc__
|
|
13
27
|
|
|
14
28
|
maxDiff = None
|
|
15
29
|
|
|
16
30
|
module_name = None # Replace in child to the name of the module to test
|
|
17
|
-
|
|
31
|
+
|
|
32
|
+
@property
|
|
33
|
+
def migrations(self):
|
|
34
|
+
"""All module migrations"""
|
|
35
|
+
return _list_migrations(self.module_name)
|
|
18
36
|
|
|
19
37
|
@classmethod
|
|
20
38
|
def setUpClass(cls):
|
|
@@ -71,14 +89,18 @@ class TestCase(testing_utils.TestCase):
|
|
|
71
89
|
def test_002_migrate_equaliry(self):
|
|
72
90
|
"""Test and compare migrations with and without postpone index using introspection"""
|
|
73
91
|
|
|
92
|
+
# Baseline: default settings (tests run with POSTPONE_INDEX_IGNORE=True).
|
|
93
|
+
call_command('migrate', self.module_name, 'zero')
|
|
94
|
+
|
|
95
|
+
migration_before = 'zero'
|
|
96
|
+
|
|
74
97
|
for migration_id in self.migrations:
|
|
75
|
-
#
|
|
76
|
-
call_command('migrate', self.module_name, 'zero')
|
|
98
|
+
# Store introspection
|
|
77
99
|
call_command('migrate', self.module_name, migration_id)
|
|
78
100
|
baseline = self.introspect_app_schema(self.module_name)
|
|
101
|
+
call_command('migrate', self.module_name, migration_before)
|
|
79
102
|
|
|
80
103
|
# With postpone_index enabled.
|
|
81
|
-
call_command('migrate', self.module_name, 'zero')
|
|
82
104
|
with override_settings(POSTPONE_INDEX_IGNORE=False):
|
|
83
105
|
call_command('migrate', self.module_name, migration_id)
|
|
84
106
|
call_command('apply_postponed', 'run', '-x')
|
|
@@ -93,6 +115,7 @@ class TestCase(testing_utils.TestCase):
|
|
|
93
115
|
migration_id,
|
|
94
116
|
),
|
|
95
117
|
)
|
|
118
|
+
migration_before = migration_id
|
|
96
119
|
|
|
97
120
|
@staticmethod
|
|
98
121
|
def _field_info_to_dict(field_info):
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"""Module Tests"""
|
|
2
|
+
|
|
3
|
+
from config import base_tests
|
|
4
|
+
|
|
5
|
+
from django.core.management import call_command
|
|
6
|
+
from django.db import IntegrityError
|
|
7
|
+
from django.test import override_settings
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class ModuleTest(base_tests.TestCase):
|
|
11
|
+
__doc__ = __doc__
|
|
12
|
+
|
|
13
|
+
module_name = __name__.split('.')[0]
|
|
14
|
+
|
|
15
|
+
def test_004_migrate_with_bad_unique_data(self):
|
|
16
|
+
"""Test migrations step by step"""
|
|
17
|
+
with override_settings(
|
|
18
|
+
POSTPONE_INDEX_IGNORE=True
|
|
19
|
+
):
|
|
20
|
+
call_command('migrate', self.module_name, 'zero')
|
|
21
|
+
with override_settings(
|
|
22
|
+
POSTPONE_INDEX_IGNORE=False
|
|
23
|
+
):
|
|
24
|
+
call_command('migrate', self.module_name, '0002')
|
|
25
|
+
|
|
26
|
+
from test_explicit_constraint.models import ExplicitConstraint1
|
|
27
|
+
|
|
28
|
+
# Duplicate field1/field2/field3 - ok without apply_postponed
|
|
29
|
+
ExplicitConstraint1.objects.create(field1='qwerty', field2='uiop', field3='asdfg')
|
|
30
|
+
duplicate = ExplicitConstraint1.objects.create(field1='qwerty', field2='uiop', field3='asdfg')
|
|
31
|
+
|
|
32
|
+
with self.assertRaises(IntegrityError):
|
|
33
|
+
# Generates error on duplicate records
|
|
34
|
+
call_command('apply_postponed', 'run', '-x')
|
|
35
|
+
duplicate.delete() # remove duplicate
|
|
36
|
+
|
|
37
|
+
call_command('apply_postponed', 'run', '-x') # Now it should be OK
|
|
38
|
+
call_command('apply_postponed', 'cleanup')
|
|
39
|
+
self._assert_postponed_sql_empty()
|
|
40
|
+
|
|
41
|
+
call_command('migrate', self.module_name, '0003')
|
|
42
|
+
|
|
43
|
+
# Duplicate field1/field2/field3 - ok
|
|
44
|
+
# after the migration deleted old unique and not yet created a new one
|
|
45
|
+
duplicate = ExplicitConstraint1.objects.create(field1='qwerty', field2='uiop', field3='asdfg')
|
|
46
|
+
|
|
47
|
+
with self.assertRaises(IntegrityError):
|
|
48
|
+
# Generates error on duplicate records
|
|
49
|
+
call_command('apply_postponed', 'run', '-x')
|
|
50
|
+
duplicate.delete() # remove duplicate
|
|
51
|
+
|
|
52
|
+
call_command('apply_postponed', 'run', '-x') # Now it should be OK
|
|
53
|
+
call_command('apply_postponed', 'cleanup')
|
|
54
|
+
self._assert_postponed_sql_empty()
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"""Module Tests"""
|
|
2
|
+
|
|
3
|
+
from config import base_tests
|
|
4
|
+
|
|
5
|
+
from django.core.management import call_command
|
|
6
|
+
from django.db import IntegrityError
|
|
7
|
+
from django.test import override_settings
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class ModuleTest(base_tests.TestCase):
|
|
11
|
+
__doc__ = __doc__
|
|
12
|
+
|
|
13
|
+
module_name = __name__.split('.')[0]
|
|
14
|
+
|
|
15
|
+
def test_004_migrate_with_bad_unique_data(self):
|
|
16
|
+
"""Test migrations step by step"""
|
|
17
|
+
with override_settings(
|
|
18
|
+
POSTPONE_INDEX_IGNORE=True
|
|
19
|
+
):
|
|
20
|
+
call_command('migrate', self.module_name, 'zero')
|
|
21
|
+
with override_settings(
|
|
22
|
+
POSTPONE_INDEX_IGNORE=False
|
|
23
|
+
):
|
|
24
|
+
call_command('migrate', self.module_name, '0002')
|
|
25
|
+
call_command('apply_postponed', 'run', '-x')
|
|
26
|
+
call_command('apply_postponed', 'cleanup')
|
|
27
|
+
self._assert_postponed_sql_empty()
|
|
28
|
+
|
|
29
|
+
from test_fields.models import UniqueField1
|
|
30
|
+
|
|
31
|
+
# Duplicate field1
|
|
32
|
+
UniqueField1.objects.create(field1='qwerty')
|
|
33
|
+
duplicate = UniqueField1.objects.create(field1='qwerty')
|
|
34
|
+
|
|
35
|
+
call_command('migrate', self.module_name, '0003') # should be OK
|
|
36
|
+
with self.assertRaises(IntegrityError):
|
|
37
|
+
# Generates error on duplicate records
|
|
38
|
+
call_command('apply_postponed', 'run', '-x')
|
|
39
|
+
duplicate.delete() # remove duplicate
|
|
40
|
+
|
|
41
|
+
call_command('apply_postponed', 'run', '-x') # Now it should be OK
|
|
42
|
+
call_command('apply_postponed', 'cleanup')
|
|
43
|
+
self._assert_postponed_sql_empty()
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Generated by Django 2.2 on 2026-02-04 09:15
|
|
2
|
+
|
|
3
|
+
import django
|
|
4
|
+
from django.db import migrations, models
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Migration(migrations.Migration):
|
|
8
|
+
|
|
9
|
+
initial = True
|
|
10
|
+
|
|
11
|
+
dependencies = [
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
operations = [
|
|
15
|
+
migrations.CreateModel(
|
|
16
|
+
name='ExplicitConstraint1',
|
|
17
|
+
fields=[
|
|
18
|
+
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
19
|
+
('field1', models.CharField(max_length=10)),
|
|
20
|
+
('field2', models.CharField(max_length=10)),
|
|
21
|
+
],
|
|
22
|
+
),
|
|
23
|
+
migrations.CreateModel(
|
|
24
|
+
name='ExplicitIndex1',
|
|
25
|
+
fields=[
|
|
26
|
+
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
27
|
+
('field1', models.CharField(max_length=10)),
|
|
28
|
+
('field2', models.CharField(max_length=10)),
|
|
29
|
+
],
|
|
30
|
+
),
|
|
31
|
+
migrations.CreateModel(
|
|
32
|
+
name='UniqueField1',
|
|
33
|
+
fields=[
|
|
34
|
+
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
35
|
+
('field1', models.CharField(max_length=10, unique=True)),
|
|
36
|
+
],
|
|
37
|
+
),
|
|
38
|
+
migrations.CreateModel(
|
|
39
|
+
name='UniqueTogether1',
|
|
40
|
+
fields=[
|
|
41
|
+
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
42
|
+
('field1', models.CharField(max_length=10)),
|
|
43
|
+
('field2', models.CharField(max_length=10)),
|
|
44
|
+
],
|
|
45
|
+
options={
|
|
46
|
+
'unique_together': {('field1', 'field2')},
|
|
47
|
+
},
|
|
48
|
+
),
|
|
49
|
+
migrations.AddIndex(
|
|
50
|
+
model_name='explicitindex1',
|
|
51
|
+
index=models.Index(fields=['field1', 'field2'], name='explicit_rename_index1_index'),
|
|
52
|
+
),
|
|
53
|
+
migrations.AddConstraint(
|
|
54
|
+
model_name='explicitconstraint1',
|
|
55
|
+
constraint=models.UniqueConstraint(condition=models.Q(('field1', '<empty>'), ('field2', '<empty>'), _negated=True), fields=('field1', 'field2'), name='explicit_rename_constraint1_non_empty'),
|
|
56
|
+
),
|
|
57
|
+
]
|
|
58
|
+
|
|
59
|
+
if django.VERSION < (5, 1):
|
|
60
|
+
operations += [
|
|
61
|
+
migrations.CreateModel(
|
|
62
|
+
name='IndexTogether1',
|
|
63
|
+
fields=[
|
|
64
|
+
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
65
|
+
('field1', models.CharField(max_length=10)),
|
|
66
|
+
('field2', models.CharField(max_length=10)),
|
|
67
|
+
],
|
|
68
|
+
options={
|
|
69
|
+
'index_together': {('field1', 'field2')},
|
|
70
|
+
},
|
|
71
|
+
),
|
|
72
|
+
]
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Generated by Django 2.2 on 2026-02-04 09:17
|
|
2
|
+
|
|
3
|
+
import django
|
|
4
|
+
from django.db import migrations, models
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Migration(migrations.Migration):
|
|
8
|
+
|
|
9
|
+
dependencies = [
|
|
10
|
+
('test_fields_rename', '0001_initial'),
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
operations = [
|
|
14
|
+
migrations.RemoveConstraint(
|
|
15
|
+
model_name='explicitconstraint1',
|
|
16
|
+
name='explicit_rename_constraint1_non_empty',
|
|
17
|
+
),
|
|
18
|
+
migrations.RemoveIndex(
|
|
19
|
+
model_name='explicitindex1',
|
|
20
|
+
name='explicit_rename_index1_index',
|
|
21
|
+
),
|
|
22
|
+
migrations.RenameField(
|
|
23
|
+
model_name='explicitconstraint1',
|
|
24
|
+
old_name='field1',
|
|
25
|
+
new_name='renamed_field1',
|
|
26
|
+
),
|
|
27
|
+
migrations.RenameField(
|
|
28
|
+
model_name='explicitconstraint1',
|
|
29
|
+
old_name='field2',
|
|
30
|
+
new_name='renamed_field2',
|
|
31
|
+
),
|
|
32
|
+
migrations.RenameField(
|
|
33
|
+
model_name='explicitindex1',
|
|
34
|
+
old_name='field1',
|
|
35
|
+
new_name='renamed_field1',
|
|
36
|
+
),
|
|
37
|
+
migrations.RenameField(
|
|
38
|
+
model_name='explicitindex1',
|
|
39
|
+
old_name='field2',
|
|
40
|
+
new_name='renamed_field2',
|
|
41
|
+
),
|
|
42
|
+
migrations.RenameField(
|
|
43
|
+
model_name='uniquefield1',
|
|
44
|
+
old_name='field1',
|
|
45
|
+
new_name='renamed_field1',
|
|
46
|
+
),
|
|
47
|
+
migrations.RenameField(
|
|
48
|
+
model_name='uniquetogether1',
|
|
49
|
+
old_name='field1',
|
|
50
|
+
new_name='renamed_field1',
|
|
51
|
+
),
|
|
52
|
+
migrations.RenameField(
|
|
53
|
+
model_name='uniquetogether1',
|
|
54
|
+
old_name='field2',
|
|
55
|
+
new_name='renamed_field2',
|
|
56
|
+
),
|
|
57
|
+
migrations.AlterUniqueTogether(
|
|
58
|
+
name='uniquetogether1',
|
|
59
|
+
unique_together={('renamed_field1', 'renamed_field2')},
|
|
60
|
+
),
|
|
61
|
+
migrations.AddIndex(
|
|
62
|
+
model_name='explicitindex1',
|
|
63
|
+
index=models.Index(fields=['renamed_field1', 'renamed_field2'], name='explicit_rename_index1_index'),
|
|
64
|
+
),
|
|
65
|
+
migrations.AddConstraint(
|
|
66
|
+
model_name='explicitconstraint1',
|
|
67
|
+
constraint=models.UniqueConstraint(condition=models.Q(('renamed_field1', '<empty>'), ('renamed_field2', '<empty>'), _negated=True), fields=('renamed_field1', 'renamed_field2'), name='explicit_rename_constraint1_non_empty'),
|
|
68
|
+
),
|
|
69
|
+
]
|
|
70
|
+
|
|
71
|
+
if django.VERSION < (5, 1):
|
|
72
|
+
operations += [
|
|
73
|
+
migrations.RenameField(
|
|
74
|
+
model_name='indextogether1',
|
|
75
|
+
old_name='field1',
|
|
76
|
+
new_name='renamed_field1',
|
|
77
|
+
),
|
|
78
|
+
migrations.RenameField(
|
|
79
|
+
model_name='indextogether1',
|
|
80
|
+
old_name='field2',
|
|
81
|
+
new_name='renamed_field2',
|
|
82
|
+
),
|
|
83
|
+
migrations.AlterIndexTogether(
|
|
84
|
+
name='indextogether1',
|
|
85
|
+
index_together={('renamed_field1', 'renamed_field2')},
|
|
86
|
+
),
|
|
87
|
+
]
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import django
|
|
2
|
+
from django.db import models
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class UniqueField1(models.Model):
|
|
6
|
+
"""Sequential migrations with unique field"""
|
|
7
|
+
|
|
8
|
+
# Changing history
|
|
9
|
+
# field1 = models.CharField(max_length=10, unique=True) # 0001
|
|
10
|
+
renamed_field1 = models.CharField(max_length=10, unique=True) # 0002
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class UniqueTogether1(models.Model):
|
|
14
|
+
"""Sequential migrations with unique-together fields"""
|
|
15
|
+
|
|
16
|
+
# Changing history
|
|
17
|
+
# field1 = models.CharField(max_length=10) # 0001
|
|
18
|
+
# field2 = models.CharField(max_length=10) # 0001
|
|
19
|
+
renamed_field1 = models.CharField(max_length=10) # 0002
|
|
20
|
+
renamed_field2 = models.CharField(max_length=10) # 0002
|
|
21
|
+
|
|
22
|
+
class Meta:
|
|
23
|
+
# unique_together = (('field1', 'field2'),)
|
|
24
|
+
unique_together = (('renamed_field1', 'renamed_field2'),)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
if django.VERSION < (5, 1):
|
|
28
|
+
class IndexTogether1(models.Model):
|
|
29
|
+
"""Sequential migrations with index-together fields"""
|
|
30
|
+
|
|
31
|
+
# Changing history
|
|
32
|
+
# field1 = models.CharField(max_length=10) # 0001
|
|
33
|
+
# field2 = models.CharField(max_length=10) # 0001
|
|
34
|
+
renamed_field1 = models.CharField(max_length=10) # 0002
|
|
35
|
+
renamed_field2 = models.CharField(max_length=10) # 0002
|
|
36
|
+
|
|
37
|
+
class Meta:
|
|
38
|
+
# index_together = (('field1', 'field2'),) # 0001
|
|
39
|
+
index_together = (('renamed_field1', 'renamed_field2'),) # 0002
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class ExplicitConstraint1(models.Model):
|
|
43
|
+
"""Sequential migrations with explicit named constraint in Meta"""
|
|
44
|
+
|
|
45
|
+
# Changing history
|
|
46
|
+
# field1 = models.CharField(max_length=10) # 0001
|
|
47
|
+
# field2 = models.CharField(max_length=10) # 0001
|
|
48
|
+
renamed_field1 = models.CharField(max_length=10) # 0002
|
|
49
|
+
renamed_field2 = models.CharField(max_length=10) # 0002
|
|
50
|
+
|
|
51
|
+
class Meta:
|
|
52
|
+
# 0001
|
|
53
|
+
# constraints = [
|
|
54
|
+
# models.UniqueConstraint(
|
|
55
|
+
# fields=['field1', 'field2'],
|
|
56
|
+
# condition=~(models.Q(field1='<empty>') & models.Q(field2='<empty>')),
|
|
57
|
+
# name='explicit_rename_constraint1_non_empty'
|
|
58
|
+
# )
|
|
59
|
+
# ]
|
|
60
|
+
# 0002
|
|
61
|
+
constraints = [
|
|
62
|
+
models.UniqueConstraint(
|
|
63
|
+
fields=['renamed_field1', 'renamed_field2'],
|
|
64
|
+
condition=~(models.Q(renamed_field1='<empty>') & models.Q(renamed_field2='<empty>')),
|
|
65
|
+
name='explicit_rename_constraint1_non_empty'
|
|
66
|
+
)
|
|
67
|
+
]
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class ExplicitIndex1(models.Model):
|
|
71
|
+
"""Sequential migrations with explicit named index in Meta"""
|
|
72
|
+
|
|
73
|
+
# field1 = models.CharField(max_length=10) # 0001
|
|
74
|
+
# field2 = models.CharField(max_length=10) # 0001
|
|
75
|
+
renamed_field1 = models.CharField(max_length=10) # 0002
|
|
76
|
+
renamed_field2 = models.CharField(max_length=10) # 0002
|
|
77
|
+
|
|
78
|
+
class Meta:
|
|
79
|
+
"""Modified Meta"""
|
|
80
|
+
# indexes = [models.Index(fields=['field1', 'field2'], name='explicit_rename_index1_index')] # 0001
|
|
81
|
+
indexes = [models.Index(fields=['renamed_field1', 'renamed_field2'], name='explicit_rename_index1_index')] # 0002
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Generated by Django 2.2 on 2026-02-04 10:34
|
|
2
|
+
|
|
3
|
+
import django
|
|
4
|
+
from django.db import migrations, models
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Migration(migrations.Migration):
|
|
8
|
+
|
|
9
|
+
initial = True
|
|
10
|
+
|
|
11
|
+
dependencies = [
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
operations = [
|
|
15
|
+
migrations.CreateModel(
|
|
16
|
+
name='ExplicitConstraint1',
|
|
17
|
+
fields=[
|
|
18
|
+
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
19
|
+
('field1', models.CharField(max_length=10)),
|
|
20
|
+
('field2', models.CharField(max_length=10)),
|
|
21
|
+
],
|
|
22
|
+
),
|
|
23
|
+
migrations.CreateModel(
|
|
24
|
+
name='ExplicitIndex1',
|
|
25
|
+
fields=[
|
|
26
|
+
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
27
|
+
('field1', models.CharField(max_length=10)),
|
|
28
|
+
('field2', models.CharField(max_length=10)),
|
|
29
|
+
],
|
|
30
|
+
),
|
|
31
|
+
migrations.CreateModel(
|
|
32
|
+
name='UniqueField1',
|
|
33
|
+
fields=[
|
|
34
|
+
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
35
|
+
('field1', models.CharField(max_length=10, unique=True)),
|
|
36
|
+
],
|
|
37
|
+
),
|
|
38
|
+
migrations.CreateModel(
|
|
39
|
+
name='UniqueTogether1',
|
|
40
|
+
fields=[
|
|
41
|
+
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
42
|
+
('field1', models.CharField(max_length=10)),
|
|
43
|
+
('field2', models.CharField(max_length=10)),
|
|
44
|
+
],
|
|
45
|
+
options={
|
|
46
|
+
'unique_together': {('field1', 'field2')},
|
|
47
|
+
},
|
|
48
|
+
),
|
|
49
|
+
migrations.AddIndex(
|
|
50
|
+
model_name='explicitindex1',
|
|
51
|
+
index=models.Index(fields=['field1', 'field2'], name='explicit_model_index1_index'),
|
|
52
|
+
),
|
|
53
|
+
migrations.AddConstraint(
|
|
54
|
+
model_name='explicitconstraint1',
|
|
55
|
+
constraint=models.UniqueConstraint(condition=models.Q(('field1', '<empty>'), ('field2', '<empty>'), _negated=True), fields=('field1', 'field2'), name='explicit_model_constraint1_non_empty'),
|
|
56
|
+
),
|
|
57
|
+
]
|
|
58
|
+
|
|
59
|
+
if django.VERSION < (5, 1):
|
|
60
|
+
operations += [
|
|
61
|
+
migrations.CreateModel(
|
|
62
|
+
name='IndexTogether1',
|
|
63
|
+
fields=[
|
|
64
|
+
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
65
|
+
('field1', models.CharField(max_length=10)),
|
|
66
|
+
('field2', models.CharField(max_length=10)),
|
|
67
|
+
],
|
|
68
|
+
options={
|
|
69
|
+
'index_together': {('field1', 'field2')},
|
|
70
|
+
},
|
|
71
|
+
),
|
|
72
|
+
]
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Generated by Django 2.2 on 2026-02-04 10:37
|
|
2
|
+
|
|
3
|
+
import django
|
|
4
|
+
from django.db import migrations, models
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Migration(migrations.Migration):
|
|
8
|
+
|
|
9
|
+
dependencies = [
|
|
10
|
+
('test_model_rename', '0001_initial'),
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
operations = [
|
|
14
|
+
migrations.RenameModel(
|
|
15
|
+
old_name='ExplicitIndex1',
|
|
16
|
+
new_name='ExplicitIndex1Renamed',
|
|
17
|
+
),
|
|
18
|
+
migrations.RenameModel(
|
|
19
|
+
old_name='ExplicitConstraint1',
|
|
20
|
+
new_name='ExplicitConstraint1Renamed',
|
|
21
|
+
),
|
|
22
|
+
migrations.RenameModel(
|
|
23
|
+
old_name='UniqueField1',
|
|
24
|
+
new_name='UniqueField1Renamed',
|
|
25
|
+
),
|
|
26
|
+
migrations.RenameModel(
|
|
27
|
+
old_name='UniqueTogether1',
|
|
28
|
+
new_name='UniqueTogether1Renamed',
|
|
29
|
+
),
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
if django.VERSION < (5, 1):
|
|
33
|
+
operations += [
|
|
34
|
+
migrations.RenameModel(
|
|
35
|
+
old_name='IndexTogether1',
|
|
36
|
+
new_name='IndexTogether1Renamed',
|
|
37
|
+
),
|
|
38
|
+
]
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import django
|
|
2
|
+
from django.db import models
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
# class UniqueField1(models.Model): # 0001
|
|
6
|
+
class UniqueField1Renamed(models.Model): # 0002
|
|
7
|
+
"""Sequential migrations with unique field"""
|
|
8
|
+
|
|
9
|
+
field1 = models.CharField(max_length=10, unique=True)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
# class UniqueTogether1(models.Model): # 0001
|
|
13
|
+
class UniqueTogether1Renamed(models.Model): # 0002
|
|
14
|
+
"""Sequential migrations with unique-together fields"""
|
|
15
|
+
|
|
16
|
+
field1 = models.CharField(max_length=10)
|
|
17
|
+
field2 = models.CharField(max_length=10)
|
|
18
|
+
|
|
19
|
+
class Meta:
|
|
20
|
+
unique_together = (('field1', 'field2'),)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
if django.VERSION < (5, 1):
|
|
24
|
+
# class IndexTogether1(models.Model): # 0001
|
|
25
|
+
class IndexTogether1Renamed(models.Model): # 0002
|
|
26
|
+
"""Sequential migrations with index-together fields"""
|
|
27
|
+
|
|
28
|
+
field1 = models.CharField(max_length=10)
|
|
29
|
+
field2 = models.CharField(max_length=10)
|
|
30
|
+
|
|
31
|
+
class Meta:
|
|
32
|
+
index_together = (('field1', 'field2'),)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
# class ExplicitConstraint1(models.Model): # 0001
|
|
36
|
+
class ExplicitConstraint1Renamed(models.Model): # 0002
|
|
37
|
+
"""Sequential migrations with explicit named constraint in Meta"""
|
|
38
|
+
|
|
39
|
+
field1 = models.CharField(max_length=10)
|
|
40
|
+
field2 = models.CharField(max_length=10)
|
|
41
|
+
|
|
42
|
+
class Meta:
|
|
43
|
+
constraints = [
|
|
44
|
+
models.UniqueConstraint(
|
|
45
|
+
fields=['field1', 'field2'],
|
|
46
|
+
condition=~(models.Q(field1='<empty>') & models.Q(field2='<empty>')),
|
|
47
|
+
name='explicit_model_constraint1_non_empty'
|
|
48
|
+
)
|
|
49
|
+
]
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
# class ExplicitIndex1(models.Model): # 0001
|
|
53
|
+
class ExplicitIndex1Renamed(models.Model): # 0002
|
|
54
|
+
"""Sequential migrations with explicit named index in Meta"""
|
|
55
|
+
|
|
56
|
+
field1 = models.CharField(max_length=10)
|
|
57
|
+
field2 = models.CharField(max_length=10)
|
|
58
|
+
|
|
59
|
+
class Meta:
|
|
60
|
+
indexes = [models.Index(fields=['field1', 'field2'], name='explicit_model_index1_index')]
|