0
# Database Migrations
1
2
Django's migrations system provides version control for database schema changes, enabling automated creation, modification, and rollback of database structures with type-safe migration operations.
3
4
## Core Imports
5
6
```python
7
# Migration base classes
8
from django.db import migrations
9
from django.db.migrations import Migration, swappable_dependency
10
11
# Migration operations
12
from django.db.migrations.operations import (
13
# Model operations
14
CreateModel, DeleteModel, RenameModel,
15
AlterModelOptions, AlterModelTable, AlterModelManagers,
16
17
# Field operations
18
AddField, RemoveField, AlterField, RenameField,
19
20
# Index and constraint operations
21
AddIndex, RemoveIndex, RenameIndex, AddConstraint, RemoveConstraint,
22
AlterIndexTogether, AlterUniqueTogether, AlterOrderWithRespectTo,
23
24
# Special operations
25
RunSQL, RunPython, SeparateDatabaseAndState
26
)
27
28
# Migration management
29
from django.db.migrations.executor import MigrationExecutor
30
from django.db.migrations.autodetector import MigrationAutodetector
31
from django.db.migrations.loader import MigrationLoader
32
from django.db.migrations.recorder import MigrationRecorder
33
from django.db.migrations.state import ProjectState, ModelState
34
from django.db.migrations.graph import MigrationGraph
35
```
36
37
## Capabilities
38
39
### Migration Base Class
40
41
Core migration class defining database schema changes and their execution order.
42
43
```python { .api }
44
class Migration:
45
"""
46
Base class representing a single database migration with operations.
47
48
Attributes:
49
operations: List of migration operations to perform
50
dependencies: List of (app_label, migration_name) tuples this migration depends on
51
run_before: List of migrations that should run after this one
52
replaces: List of migrations this migration replaces
53
initial: Whether this is an initial migration
54
atomic: Whether to run operations in a transaction
55
name: Migration name
56
app_label: App this migration belongs to
57
"""
58
operations: Sequence[Operation]
59
dependencies: Sequence[tuple[str, str]]
60
run_before: Sequence[tuple[str, str]]
61
replaces: Sequence[tuple[str, str]]
62
initial: bool | None
63
atomic: bool
64
name: str
65
app_label: str
66
67
def __init__(self, name: str, app_label: str) -> None: ...
68
def mutate_state(self, project_state: ProjectState, preserve: bool = False) -> ProjectState: ...
69
def apply(self, project_state: ProjectState, schema_editor: BaseDatabaseSchemaEditor, collect_sql: bool = False) -> ProjectState: ...
70
def unapply(self, project_state: ProjectState, schema_editor: BaseDatabaseSchemaEditor, collect_sql: bool = False) -> ProjectState: ...
71
```
72
73
### Model Operations
74
75
Operations for creating, modifying, and deleting models.
76
77
```python { .api }
78
class CreateModel(Operation):
79
"""Create a new model with specified fields and options."""
80
def __init__(self, name: str, fields: list[tuple[str, Field]], options: dict = None, bases: tuple = None, managers: list = None) -> None: ...
81
82
class DeleteModel(Operation):
83
"""Delete an existing model and its database table."""
84
def __init__(self, name: str) -> None: ...
85
86
class RenameModel(Operation):
87
"""Rename a model and its database table."""
88
def __init__(self, old_name: str, new_name: str) -> None: ...
89
90
class AlterModelOptions(Operation):
91
"""Change model Meta options (permissions, ordering, etc.)."""
92
def __init__(self, name: str, options: dict) -> None: ...
93
94
class AlterModelTable(Operation):
95
"""Change the database table name for a model."""
96
def __init__(self, name: str, table: str) -> None: ...
97
98
class AlterModelManagers(Operation):
99
"""Change the managers available on a model."""
100
def __init__(self, name: str, managers: list) -> None: ...
101
```
102
103
### Field Operations
104
105
Operations for adding, removing, and modifying model fields.
106
107
```python { .api }
108
class AddField(Operation):
109
"""Add a new field to a model."""
110
def __init__(self, model_name: str, name: str, field: Field, preserve_default: bool = True) -> None: ...
111
112
class RemoveField(Operation):
113
"""Remove a field from a model."""
114
def __init__(self, model_name: str, name: str) -> None: ...
115
116
class AlterField(Operation):
117
"""Change the definition of a field."""
118
def __init__(self, model_name: str, name: str, field: Field, preserve_default: bool = True) -> None: ...
119
120
class RenameField(Operation):
121
"""Rename a field in a model."""
122
def __init__(self, model_name: str, old_name: str, new_name: str) -> None: ...
123
```
124
125
### Index and Constraint Operations
126
127
Operations for managing database indexes and constraints.
128
129
```python { .api }
130
class AddIndex(Operation):
131
"""Add a database index."""
132
def __init__(self, model_name: str, index: Index) -> None: ...
133
134
class RemoveIndex(Operation):
135
"""Remove a database index."""
136
def __init__(self, model_name: str, name: str) -> None: ...
137
138
class RenameIndex(Operation):
139
"""Rename a database index."""
140
def __init__(self, model_name: str, old_name: str, new_name: str) -> None: ...
141
142
class AddConstraint(Operation):
143
"""Add a database constraint."""
144
def __init__(self, model_name: str, constraint: BaseConstraint) -> None: ...
145
146
class RemoveConstraint(Operation):
147
"""Remove a database constraint."""
148
def __init__(self, model_name: str, name: str) -> None: ...
149
150
class AlterIndexTogether(Operation):
151
"""Change the index_together option for a model."""
152
def __init__(self, name: str, index_together: set[tuple[str, ...]]) -> None: ...
153
154
class AlterUniqueTogether(Operation):
155
"""Change the unique_together option for a model."""
156
def __init__(self, name: str, unique_together: set[tuple[str, ...]]) -> None: ...
157
```
158
159
### Special Operations
160
161
Operations for custom SQL and Python code execution.
162
163
```python { .api }
164
class RunSQL(Operation):
165
"""Execute raw SQL during migration."""
166
def __init__(self, sql: str | list[str], reverse_sql: str | list[str] = None, state_operations: list[Operation] = None, hints: dict = None, elidable: bool = False) -> None: ...
167
168
class RunPython(Operation):
169
"""Execute Python code during migration."""
170
def __init__(self, code: callable, reverse_code: callable = None, atomic: bool = None, hints: dict = None, elidable: bool = False) -> None: ...
171
172
class SeparateDatabaseAndState(Operation):
173
"""Separate database operations from state changes."""
174
def __init__(self, database_operations: list[Operation] = None, state_operations: list[Operation] = None) -> None: ...
175
```
176
177
### Migration Management
178
179
Classes for loading, executing, and managing migrations.
180
181
```python { .api }
182
class MigrationExecutor:
183
"""Executes migrations against a database."""
184
def __init__(self, connection, progress_callback: callable = None) -> None: ...
185
def migration_plan(self, targets: list[tuple[str, str]], clean_start: bool = False) -> list[tuple[Migration, bool]]: ...
186
def migrate(self, targets: list[tuple[str, str]], plan: list[tuple[Migration, bool]] = None, state: ProjectState = None, fake: bool = False, fake_initial: bool = False) -> ProjectState: ...
187
188
class MigrationAutodetector:
189
"""Detects changes between model states and generates migrations."""
190
def __init__(self, from_state: ProjectState, to_state: ProjectState, questioner: MigrationQuestioner = None) -> None: ...
191
def changes(self, graph: MigrationGraph, trim_to_apps: set[str] = None, convert_apps: set[str] = None, migration_name: str = None) -> dict[str, list[Migration]]: ...
192
193
class MigrationLoader:
194
"""Loads migration files from disk."""
195
def __init__(self, connection, load: bool = True, ignore_no_migrations: bool = False) -> None: ...
196
def get_migration_by_prefix(self, app_label: str, name_prefix: str) -> Migration: ...
197
198
class MigrationRecorder:
199
"""Records which migrations have been applied."""
200
def __init__(self, connection) -> None: ...
201
def record_applied(self, app: str, name: str) -> None: ...
202
def record_unapplied(self, app: str, name: str) -> None: ...
203
def applied_migrations(self) -> set[tuple[str, str]]: ...
204
```
205
206
### Migration State
207
208
Classes representing the state of the project and models during migration.
209
210
```python { .api }
211
class ProjectState:
212
"""Represents the state of the entire project at a point in migration history."""
213
def __init__(self, models: dict = None, real_apps: set[str] = None) -> None: ...
214
def add_model(self, model_state: ModelState) -> None: ...
215
def remove_model(self, app_label: str, model_name: str) -> None: ...
216
def reload_model(self, app_label: str, model_name: str, delay: bool = False) -> None: ...
217
def clone(self) -> ProjectState: ...
218
219
class ModelState:
220
"""Represents the state of a single model at a point in migration history."""
221
def __init__(self, app_label: str, name: str, fields: list[tuple[str, Field]], options: dict = None, bases: tuple = None, managers: list = None) -> None: ...
222
def clone(self) -> ModelState: ...
223
def render(self, apps: Apps) -> type[Model]: ...
224
```
225
226
### Utility Functions
227
228
```python { .api }
229
def swappable_dependency(value: str) -> SwappableTuple:
230
"""Create a dependency that can be swapped for a different model."""
231
232
class SwappableTuple(tuple[str, str]):
233
"""Tuple representing a swappable model dependency."""
234
setting: str
235
def __new__(cls, value: tuple[str, str], setting: str) -> SwappableTuple: ...
236
```
237
238
## Migration Exceptions
239
240
```python { .api }
241
# Migration-specific exceptions
242
class InvalidMigrationPlan(Exception): ...
243
class IrreversibleError(RuntimeError): ...
244
class NodeNotFoundError(LookupError): ...
245
class MigrationSchemaMissing(DatabaseError): ...
246
class CircularDependencyError(Exception): ...
247
class InconsistentMigrationHistory(Exception): ...
248
```
249
250
## Usage Examples
251
252
**Creating a simple migration:**
253
254
```python
255
from django.db import migrations, models
256
257
class Migration(migrations.Migration):
258
dependencies = [
259
('myapp', '0001_initial'),
260
]
261
262
operations = [
263
migrations.CreateModel(
264
name='Article',
265
fields=[
266
('id', models.AutoField(primary_key=True)),
267
('title', models.CharField(max_length=200)),
268
('content', models.TextField()),
269
('created_at', models.DateTimeField(auto_now_add=True)),
270
],
271
),
272
]
273
```
274
275
**Running custom Python code in migration:**
276
277
```python
278
def create_default_categories(apps, schema_editor):
279
Category = apps.get_model('myapp', 'Category')
280
Category.objects.bulk_create([
281
Category(name='Technology'),
282
Category(name='Science'),
283
])
284
285
class Migration(migrations.Migration):
286
operations = [
287
migrations.RunPython(create_default_categories),
288
]
289
```