Migrationen
Um die Daten, die den Models zugewiesen werden, später auch persistent
speichern zu können, müssen wir die entsprechenden Datenbank-Tabellen
anlegen. Dies geschieht aber nicht manuell, sondern wird über sogenannte
Migrationen
gelöst.
Ein Wort vorweg
Django erstellt also nur auf Grundlage unserer Models entsprechende Datenbank-Tabellen. Das ist in vielen Web-Frameworks übliches Vorgehen, da ein Projekt meist von mehreren Entwicklern und Designern erstellt wird. Um dem gesamten Team die selbe Datenbankstruktur zu garantieren, sind Migrationsdateien ein vorteilhafter Weg, dies zu erreichen.
Immer, wenn wir nun ein Model verändern, müssen wir folglich auch eine neue Migrations-Datei erstellen, die als Grundlage für die eigentliche Migration dient.
Warnung
Löschen von Migrationsdateien
Von Django erstellte Migrationsdateien sollten nur in den seltensten Fällen gelöscht oder manuell bearbeitet werden.
Gerade am Anfang eines Projekts passiert es aber oft, dass man ab und an
reinen Tisch
machen und alle Migrationsdateien löschen möchte.
Unter Linux/Unix-Systemen bieten sich folgende Kommandos an, um die Dateien zu löschen:
find . -path "*/migrations/*.py" -not -name "__init__.py" -delete
find . -path "*/migrations/*.pyc" -delete
Die __init__.py
Dateien werden nicht aus den Migrations-Verzeichnissen
gelöscht, da es sich bei diesen um Python-Packages handeln muss.
Zusätzlich werden die kompilierten pyc
Dateien entfernt.
Best Practice: Versionieren von Migrations-Dateien
Erstellte Migrationsdateien müssen auf jeden Fall ins git
- Repository
übernommen und versioniert werden. Wird dies nicht gemacht, haben später womöglich nicht
alle Team-Member die selbe Datenbankstruktur. Das führt unweigerlich ins
Chaos.
Best Practice: Arbeiten im Team
Das Ändern eines Models und das sich daraus ergebende Ändern der
Persistenz-Ebene eines Softwareprojekts ist eine Aktion, die gut überlegt
und geplant werden muss, vor allem, wenn im Team gearbeitet wird. Als
best practice
gilt, dass Änderungen am Model im Team abgesprochen
werden und alle anderen Team-Mitglieder sich diese Änderung und die
entsprechenden Migrationsdateien dann auch
zeitnah in ihr lokales Repository ziehen.
Migrations-Datei erstellen
Damit die Models in der Datenbank verfügbar sind, müssen sie migriert werden.
Dazu erstellen wir erstmal die aktuelle Migrationsdatei für die App events
:
python manage.py makemigrations events
Wir bekommen als Ausgabe die Meldung, dass Migatrions-Dateien erstellt wurden:
Migrations for 'events':
events/migrations/0001_initial.py
- Create model Category
- Create model Event
Migrations for 'user':
user/migrations/0001_initial.py
- Create model User
Im Verzeichnis event_manager/events/migrations/
wurde jetzt eine neue Datei
angelegt, und zwar die Datei 0001_initial.py
. Das ist die Migrationsdatei,
die gerade erstellt wurde.
Würden wir den makemigrations
-Befehl jetzt nochmal ausführen, würde die
Meldung kommen, dass keine neuen Änderungen verfügbar sind. D.h., nur, wenn wir
das Model ändern, erstellen wir auch eine neue Migrations-Datei.
migrate und makemigrations
migrate
und makemigrations
sind die beiden Subkommandos, die nötig
sind, um die Datenbank zu migrieren. makemigrations
erstellt die
Migrationsdatei, migrate
führt anhand der erstellten Migrationsdateien
die Migration(en) durch. Beide Befehle lassen sich optional auf eine konkrete
App einschränken: Wenn wir also nur Migrationsdateien für die App
events
erstellen wollen, können wir das mit python manage.py
makemigrations events
bewerkstelligen.
Hochzählen der Migrationsdateien
Bei jeder erfolgreich durchgeführten makemigrations
-Aktion wird eine neue Migrationsdatei erstellt. Diese Dateien haben einen numerischen Präfix (0001), der pro Erstellung inkrementiert wird. Der zweite Teil des Dateinamens wird von Django selbst generiert und bezieht sich auf die letzte Änderung im Model, zb. 0004_alter_event_options.py
.
Nun müssen wir noch die Migrationsdatei für das User-Model erstellen:
python manage.py makemigrations user
Damit sind von unserer Seite alle nötigen Migrationsdatei erstellt. Wir können die Änderungen nun tatsächlich in die Datenbank schreiben.
Migration durchführen
Mit dem nun folgenden Befehl führen wir alle bisher noch migrierten Migrationsdateien aus. Dazu gehören auch die von den eingebauten Django-Apps selbst, denn auch diese haben wir bisher nicht migriert.
python manage.py migrate
Nun wurden die Datenbank-Tabellen für die verschiedenen Apps angelegt. In der Ausgabe sehen wir auch die Migration 0001 für die App events.
Operations to perform:
Apply all migrations: admin, auth, contenttypes, events, sessions, user
Running migrations:
Applying contenttypes.0001_initial... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0001_initial... 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 auth.0010_alter_group_name_max_length... OK
Applying auth.0011_update_proxy_permissions... OK
Applying auth.0012_alter_user_first_name_max_length... OK
Applying user.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 events.0001_initial... OK
Applying sessions.0001_initial... OK
Auch das Migrieren würde sich mit python manage.py migrate events
auf die
Events-App eingrenzen lassen.
Um zu Prüfen, wie das SQL aussieht, welches eine Migrationsdatei erstellt, kann dieser Befehl ausgeführt werden:
python manage.py sqlmigrate events 0001
Das hier gezeigte SQL ist in Abhängigkeit des in den settings.py
gewählten
Datenbanksystems erstellt worden. Je nach verwendetem System variiert das SQL also.
Wir verwenden in diesem Buch sqlite3
, deshalb wird hier auch der sqlite3-Dialekt gezeigt.
Sqlite-Browser und SQLite-Extension
Um sich die Tabellen-Struktur komfortabel anzeigen zu lassen, bietet sich für sqlite3
der Sqlite-Browser an, der hier heruntergeladen werden kann: https://sqlitebrowser.org/
Mit dem Programm lässt sich die Datei event_manager/db.sqlite3
des Projekts öffnen.
Daneben gibt es zum Betrachten der Datenbank zum Beispiel für den VS Code Editor
einfach zu installierende Plugins, zum Beispiel ie SQLite-Extension
.
In der Tabelle django_migrations
der sqlite3-Datenbank unseres Eventmanagers finden sich alle bisher durchgeführten Migrationen. Diese korrespondieren auch mit den Migrationsdateien der jeweiligen Apps. Man sieht überdies nicht nur die beiden von uns erstellten apps user
und events
, sondern auch noch die django-eigenen Apps, wie auth
oder sessions
.
Tabula Rasa - Migrationen löschen
Es kann gerade im Entwicklungsprozess passieren, dass man an einen Punkt kommt, an dem es die beste Lösung ist, die bestehenden Migrationsdateien zu löschen. Dann sollte nicht vergessen werden, die dazugehörigen Tabellen inkl. der django_migrations
zu löschen. Generell gehen bei solchen Aktionen auch alle Daten verloren, was aber im Entwicklungsprozess meist weniger wichtig ist.
Wir können im sqlite-Browser auch nach den Tabellen unserer Models suchen und uns die Struktur angucken. Zum Beispiel finden wir im Sqlite-Browser auch die Tabelle für die events:
Tabellenname
Django hat auf Basis unserer Models und dem App-Namen entsprechende
Tabellenfelder erstellt. Das Default-Schema ist immer
<APP_NAME_LOWERCASE>_<MODEL_NAME_LOWERCASE>
. In unserem Fall also
events_event
oder events_category.
Falls man für sein Model einen anderen Tabellennamen haben möchte, kann man
dies in der Meta-Klasse des Models anpassen. Nehmen wir an, wir würden
unsere Tabelle gerne event_table
nennen:
class Meta:
ordering = ["name"]
verbose_name_plural = "Events"
db_table = "event_table"
weitere nützliche manage.py Commands
python manage.py showmigrations
Wir können uns eine Übersicht aller existierenden Migrationsdateien ausgeben lassen.
python manage.py check
Bevor wir eine Makemigrations durchführen, können wir mit
check
prüfen, ob alles in Ordnung ist und es keine Fehler in der Codebase gibt.
VS Code Extension SQLite
Für Visual Studio Code Nutzer empfiehlt es sich, neben dem Sqlite-Browser die SQLite - Extension
von alexcvzz
zu installieren.
Dabei handelt es sich um ein Editor-Addon, welches sich in Visual Studio Code installieren lässt.
Mit dieser Extension kann man bequem lesende Anfragen an
sqlite3
-Datenbanken durchführen und den aktuellen Zustand der Datenbank
betrachten.
Mehr zu dieser Extension hier: https://marketplace.visualstudio.com/items?itemName=alexcvzz.vscode-sqlite
Weiterführende Informationen
Cookbook
An dieser Stelle sei nochmal das Cookbook 2 zum Thema manage.py
verwiesen. Dieses findet ihr im Kapitel Cookbooks
.