Datenbank exportieren
Wir können unsere Daten aus der Datenbank mit einem einfachen Befehl serialisiert im Json-Format exportieren und ein Backup erstellen. Dieses Backup heisst Fixture
.
Was sind Fixtures?
Ein Fixture ist eine Sammlung von Dateien, die den serialisierten Inhalt der Datenbank enthalten. Jedes Fixture hat einen eindeutigen Namen, und die Dateien, aus denen das Fixture besteht, können verteilt über mehrere Verzeichnisseund Anwendungen sein.
Fixtures sind also json-Dateien, die den Zustand der aktuellen Datenbank abbilden. Wir können sie nutzen, um eine Applikation mit Initial-Daten zu versorgen, um ein Backup zu erstellen, um unsere Applikation zu testen oder unseren Entwicklungsserver mit den Fixtures zu starten.
Wir können Fixtures auch im XML-Format erstellen.
Erstellen der Fixtures
Um ein Fixture eines Models zu erstellen, bietet manage.py
das Subkommando dumpdata
.
Wir wollen die Fixtures für die Event-App zentral an einem Ort speichern, deshalb legen wir unter event_manager/events
ein neues Verzeichnis namens fixtures
an.
events
├───fixtures
├───management
│ └───commands
├───migrations
In dieses speichern wir die Fixtures für die Testuser sowie die Fixtures für die Events inkl. der Kategorien.
Nun erstellen wir die Fixtures für die Testuser, da die Events eine Referenz auf die User haben.
# fixture für user erstellen (da events referenz auf user haben)
python manage.py dumpdata user --indent 4 > events/fixtures/users.json
Genauso erstellen wir auch noch die Fixtures für die Events.
# fixture für events (category, events, reviews)
python manage.py dumpdata events --indent 4 > events/fixtures/events.json
Wo liegen Fixtures?
Django sucht an drei Orten nach den Fixtures:
Im Verzeichnis
fixtures
jeder installierten Appin den Verzeichnissen, die in
FIXTURE_DIRS
angegeben sindin der Pfadangabe, mit der das Fixture aufgerufen wird.
Mehr zu Fixtures hier: https://docs.djangoproject.com/en/ref/howto/initial-data/ https://dev.to/hussainislam/django-fixtures-seeding-databases-5ai
Good practice: Fixtures nicht versionieren
Fixtures sind Daten und gehören schon alleine deshalb nicht in die Versionskontrolle.
Sie sollten also zum Beispiel in der .gitignore
-Datei ignoriert werden:
fixtures/
Testserver mit Fixtures starten
Wenn wir unsere App mit dem Befehl python manage.py runserver
starten, werden die Daten, die in der Datenbank gespeichert sind, genutzt. Ändern wir diese Daten, ändern wir sie folglich auch in der Datenbank. Das ist normalerweise auch das gewünschte Verhalten einer datenbankorientierten Web-Applikation.
Wir können unseren Testserver aber auch auf Basis der Fixtures laufen lassen. Um nebenher auch noch den Runserver laufen zu lassen, nutzen wir nun Port 7000.
python manage.py testserver --addrport 7000 events.json users.json
Was passiert hier?
es wird eine in memory Testdatenbank erstellt (wie das auch bei Testing der Fall sein wird)
Diese Datenbank wird mit den Daten der Fixtures befüllt
Der Django Entwicklungsserver wird gestartet (runserver)
Statt unserer herkömmlichen Datenbank wird auf diese temporäre Datenbank referenziert.
Unter http://127.0.0.1:7000/admin
können wir uns jetzt mit unserem Test-Admin in die Administrationsoberfläche einloggen und Daten eintragen oder löschen. Unsere App unter http://127.0.0.1:8000/admin
bleibt davon unberührt.
Encoding Error unter Windows
Unter Windows kann es beim Hochfahren des Test-Servers zu einem Encoding - Fehler kommen, da die erstellten
Fixtures unter Umständen als UTF-16 exportiert wurden und der
Byte-Order-Mark
am Anfang des Dokuments nicht
dekodiert werden kann. Hier könnte es unter Umständen helfen, das
Dump-Kommando wie folgt auszuführen.
python -Xutf8 ./manage.py dumpdata --indent 4 > events/fixtures/events.json
python -Xutf8 ./manage.py dumpdata --indent 4 > events/fixtures/users.json
Wozu einen Testserver mit Fixtures starten?
Es gibt zwei Hauptgründe, warum man einen Testserver mit den Fixtures starten will. Der erste Grund ist sicher später das Testen des Frontends (zb. mit https://de.wikipedia.org/wiki/Selenium). Wir wollen mit vielen Daten testen und dabei auch einige Daten verändern. Immer wieder Testdaten einzuspielen wäre mühselig und zeitintensiv.