Migrations¶
python manage.py makemigrations # write a migration for model changes
python manage.py makemigrations -m "add tags"
python manage.py migrate # apply everything
python manage.py migrate <revision> # move up or down to a revision
python manage.py migrate zero # unapply everything (empty database)
(Or from Python: fyro.migrations.makemigrations() and fyro.migrations.migrate(target); both are synchronous.)
- Migration files live in
<project>/migrations/, namedYYYY_MM_DD_HHMM-<revision>_<slug>.py. There is noalembic.iniand noenv.pyto maintain: fyro keeps them internal. - When nothing changed, no file is written.
makemigrationsneeds the database to be at the latest migration first; runmigrate.- Two migrations made from the same parent (usually on two branches) are an error naming both; set one file's
down_revisionto the other's revision.
Changes to tables that already have rows¶
makemigrations never writes a migration that would fail on existing data:
| Change | What the migration does |
|---|---|
Add a required field with a constant default (views: int = 0) |
Existing rows get the default; no database default is left behind. |
Add a required field with default_factory=uuid.uuid4, datetime.now or date.today |
Existing rows get gen_random_uuid(), now() or CURRENT_DATE (one value per row for UUIDs). |
Make an optional field required (T \| None to T) |
Empty rows are filled from the default first. |
| Any of the above with no usable default, or a unique field with a constant default | Refused, with a message saying what to do. |
| Add an optional field | A plain column add. |
Renames¶
Alembic cannot detect renames: renaming a field shows up as drop the old column, add the new one, which loses that column's data. makemigrations logs a warning when one migration drops and adds columns on the same table. Edit the generated migration if you meant a rename.