-
Notifications
You must be signed in to change notification settings - Fork 37
ITEP-88294: Fix database migration flow #1144
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
039c550
96d26c5
23f8d8d
0968474
491e473
154c85b
4254d2f
90d0488
7f2972d
7404b53
9ea7448
7c9a8be
4e7645d
1058846
74adad9
73361cf
54fdfa8
70058d8
aab521e
89f7bf4
3a1e0a7
b449578
7797509
9af0ff3
39f818d
26321bd
a9417db
a41ff1c
6395dd2
0636785
2cb8972
6ca8af4
ab2920d
fc7eb29
b450181
6440fae
926cd88
66a4582
7fd8089
e0c3e22
4de153f
ddab550
7aaac9f
3964b64
90a4bbc
84dbcd1
186da28
c7d0b6c
276500b
e52ddaf
4bf11f2
97ffa62
86b96b3
61cfcd4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,180 @@ | ||
| # SPDX-FileCopyrightText: (C) 2025 Intel Corporation | ||
|
|
||
| # SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| # Django Migrations Guide | ||
|
|
||
| ## Overview | ||
|
|
||
| SceneScape uses Django's migration system to manage database schema changes. Migration files are version-controlled and applied at runtime to ensure consistent database upgrades across releases. | ||
|
|
||
| ## Important: Proper Migration Usage | ||
|
|
||
| **DO NOT** run `makemigrations` at runtime or in production. Migrations should be: | ||
|
|
||
| 1. Generated during development | ||
| 2. Reviewed and tested | ||
| 3. Committed to version control | ||
| 4. Built into the Docker image | ||
| 5. Applied at runtime via `migrate` only | ||
|
|
||
| ## Creating Migrations | ||
|
|
||
| ### For Local Development | ||
|
|
||
| When you modify Django models in `src/manager/models.py`, follow these steps: | ||
|
|
||
| 1. **Make your model changes** in `src/manager/models.py` | ||
|
|
||
| 2. **Generate migration file** using the generate_migrations.sh script: | ||
|
|
||
| ```bash | ||
| bash manager/tools/generate_migrations.sh | ||
| ``` | ||
|
|
||
| 3. **Review the generated migration** in `src/manager/migrations/`: | ||
|
|
||
| ```bash | ||
| ls -la manager/src/manager/migrations/ | ||
| ``` | ||
|
|
||
| 4. ** Re-build manager** | ||
|
|
||
| ```bash | ||
| make manager | ||
| ``` | ||
|
|
||
| 5. **Verify the migration is being applied **: | ||
|
|
||
| ```bash | ||
| docker compose down web && docker compose up web | ||
| ``` | ||
|
|
||
| 6. **Check migration status**: | ||
|
|
||
| ```bash | ||
| bash manager/tools/generate_migrations.sh --show --network scenescape_scenescape --dbhost pgserver --dbport 5432 | ||
| ``` | ||
|
|
||
| 7. **Commit the migration file** to version control: | ||
| ```bash | ||
| git add manager/src/manager/migrations/XXXX_*.py | ||
| git commit -m "Add migration for [describe changes]" | ||
| ``` | ||
|
|
||
| ### For CI/CD and Release Process | ||
|
|
||
| Migration generation should be automated as part of the release build: | ||
|
|
||
| 1. **In CI/CD pipeline**, after model changes are merged: | ||
|
|
||
| ```bash | ||
| # If migrations are needed, generate them | ||
| bash manager/tools/generate_migrations.sh | ||
|
|
||
| # Build the manager image | ||
| make manager | ||
|
|
||
| # Review migrations | ||
| manager/src/manager/migrations | ||
|
|
||
| # Commit and push the generated migrations | ||
| git add manager/src/manager/migrations/ | ||
| git commit -m "Generate migrations for release" | ||
| git push | ||
| ``` | ||
|
|
||
| 2. **Rebuild the image** with the new migrations included | ||
|
|
||
| ## Migration Naming Convention | ||
|
|
||
| Django automatically names migrations as: | ||
|
|
||
| - `0001_initial.py` - Initial schema | ||
| - `0002_<description>.py` - Subsequent changes | ||
| - `0003_<description>.py` - More changes | ||
| - etc. | ||
|
|
||
| For releases, you may want to include version information in the description: | ||
|
|
||
| ```bash | ||
| docker compose exec manager python manage.py makemigrations manager --name release_2026_1_0 | ||
| ``` | ||
|
|
||
| This creates: `0002_release_2026_1_0.py` | ||
|
|
||
| ## Applying Migrations | ||
|
|
||
| Migrations are applied automatically at container startup via the `migrate` command in `config/scenescape-init`. | ||
|
|
||
| To manually apply migrations: | ||
|
|
||
| ```bash | ||
| docker exec -it -w /home/scenescape/SceneScape scenescape-web-1 \ | ||
| python manage.py migrate | ||
| ``` | ||
|
|
||
| ## Checking Migration Status | ||
|
|
||
| View all migrations and their application status: | ||
|
|
||
| ```bash | ||
| docker exec -it -w /home/scenescape/SceneScape scenescape-web-1 \ | ||
| python manage.py showmigrations | ||
| ``` | ||
|
|
||
| Example output: | ||
|
|
||
| ``` | ||
| manager | ||
| [X] 0001_initial | ||
| [X] 0002_release_2026_1_0 | ||
| [ ] 0003_add_new_field | ||
| ``` | ||
|
|
||
| ## Troubleshooting | ||
|
|
||
| ### Migration conflicts | ||
|
|
||
| If multiple developers create migrations in parallel: | ||
|
|
||
| 1. Merge the code | ||
| 2. Run `makemigrations --merge` to create a merge migration | ||
| 3. Test the merge migration | ||
| 4. Commit the merge migration file | ||
|
|
||
| ### Reverting migrations | ||
|
|
||
| ```bash | ||
| # Revert to a specific migration | ||
| docker exec -it -w /home/scenescape/SceneScape scenescape-web-1 \ | ||
| python manage.py migrate manager 0001_initial | ||
|
|
||
| # Revert all migrations for an app | ||
| docker exec -it -w /home/scenescape/SceneScape scenescape-web-1 \ | ||
| python manage.py migrate manager zero | ||
| ``` | ||
|
|
||
| ### Fake migrations | ||
|
|
||
| In rare cases (like database schema already matches): | ||
|
|
||
| ```bash | ||
| docker exec -it -w /home/scenescape/SceneScape scenescape-web-1 \ | ||
| python manage.py migrate manager --fake | ||
| ``` | ||
|
|
||
| ## Best Practices | ||
|
|
||
| 1. **Always review generated migrations** before committing | ||
| 2. **Test migrations** on a copy of production data | ||
| 3. **Keep migrations small** - one logical change per migration | ||
| 4. **Never edit applied migrations** - create a new migration instead | ||
| 5. **Document complex migrations** with comments in the migration file | ||
| 6. **Backup database** before applying migrations in production | ||
|
|
||
| ## References | ||
|
|
||
| - [Django Migrations Documentation](https://docs.djangoproject.com/en/5.2/topics/migrations/) | ||
| - [Django makemigrations Command](https://docs.djangoproject.com/en/5.2/ref/django-admin/#makemigrations) | ||
| - [Django migrate Command](https://docs.djangoproject.com/en/5.2/ref/django-admin/#migrate) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -244,21 +244,26 @@ fi | |
| export -n DBPASS SUPASS | ||
|
|
||
| if [ -n "$DBTYPE" ]; then | ||
| cd ${MANAGERDIR} | ||
| # Determine "first run" using the marker (or another check) | ||
| CREATEDB=0 | ||
| MIGRATIONS=${DBROOT}/migrations/__init__.py | ||
| if [ ! -e ${MIGRATIONS} ] ; then | ||
| CREATEDB=1 | ||
| MIGRATIONS_MARKER="${DBROOT}/migrations/__init__.py" | ||
| if [ ! -e "${MIGRATIONS_MARKER}" ]; then | ||
| CREATEDB=1 | ||
| mkdir -p "$(dirname "${MIGRATIONS_MARKER}")" | ||
| touch "${MIGRATIONS_MARKER}" | ||
| fi | ||
|
Comment on lines
+250
to
254
|
||
| if [ ${CREATEDB} = 1 ] ; then | ||
| mkdir -p ${DBROOT}/migrations | ||
| touch ${MIGRATIONS} | ||
| echo "Checking if database is empty..." | ||
| if ! (./manage.py showmigrations | grep -q '\[X\]'); then | ||
| echo "Database is empty — running initial migrations..." | ||
| (./manage.py makemigrations manager) | ||
| (./manage.py migrate) | ||
| fi | ||
|
|
||
| # ALWAYS apply migrations | ||
| cd ${MANAGERDIR} | ||
| echo "==> Applying pending migrations..." | ||
| ./manage.py migrate --noinput | ||
|
|
||
| if [ "${CREATEDB}" -eq 1 ] && [ -n "${EXAMPLEDB:-}" ]; then | ||
| echo "==> Preloading example DB..." | ||
| mkdir -p "${DBROOT}/media" | ||
| tar -C "${DBROOT}/media" -xf "${EXAMPLEDB}" | ||
| ./manage.py loaddata "${DBROOT}/media/data.json" | ||
| rm -f "${DBROOT}/media/data.json" "${DBROOT}/media/meta.json" | ||
| fi | ||
|
Comment on lines
+261
to
267
|
||
|
|
||
| ./manage.py updatedbstatus --not-ready | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On clear repo, without scenescape deployed it is failing. I suggesting adding pre-requirements in readme with minimal requirements.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I deployed scenescape. But when I run script I got errors about unable to connect to postgres.