Ich bin auf Django 1.8 (mit pytest), und ich habe die folgende Konfiguration:Wie können Datenbankeinstellungen in Django-Tests überschrieben werden?
- A
default
und einereadonly
Datenbank von einemMasterSlaveRouter
verwaltet, die DB auf eine Verbindung oder die andere je nach leitet Anrufe ob sie‘ Lese- oder Schreiboperationen. - In meiner Entwicklungsumgebung haben beide Einträge im
settings.DATABASES
Wörterbuch die gleiche Konfiguration (sie verwenden nur eine andere Verbindung, aber die Datenbank ist die gleiche). In meiner Testumgebung gibt es nur einedefault
Datenbank. - Ich habe ein
post_save
Signal ausgelöst, wenn ein ModellFoo
gespeichert wird. - Ich habe eine atomare Operation (mit
@transaction.atomic
dekoriert), die eineFoo
Instanz ändert und.save()
darauf zweimal aufruft. Da kein benutzerdefinierter Parameterusing
an den Decorator übergeben wird, ist die Transaktion nur in der Datenbankdefault
aktiv.
Der post_save
Rückruf erstellt einen Bar
Datensatz mit einem OneToOneField
zeigt auf Foo
, aber erst nach Überprüfung, ob ein Bar
Datensatz mit diesem foo_id
existiert bereits (in der Reihenfolge IntegrityError
zu vermeiden). Diese Prüfung wird durch Ausführen dieser Abfrage getan:
already_exists = Bar.filter(foo=instance).exists()
Diese Ordnung ist das erste Mal, der post_save
Rückruf aufgerufen wird. Ein Bar
Datensatz wird erstellt und alles funktioniert einwandfrei. Das zweite Mal, obwohl eine solche Bar
Instanz gerade in der vorherigen Foo
Speichern erstellt wurde, da Filterung eine Leseoperation ist, wird es unter Verwendung der readonly
Verbindung durchgeführt, und daher endet already_exists
enthält den Wert False
und die Erstellung von a Es wird ein neuer Datensatz ausgelöst, der schließlich einen IntegrityError auslöst, da bei der Ausführung der Erstellungsoperation auf der default
-Verbindung bereits ein Datensatz mit dieser vorhanden ist.
Ich habe versucht, das DATABASES
Wörterbuch von dev_settings zu test_settings zu kopieren, aber das hat viele Tests abgebrochen. Ich las dann über die override_settings
Dekorateurin und dachte, es wäre perfekt für meine Situation. Zu meiner Überraschung hat es jedoch nicht funktioniert. Es scheint, dass an einem Punkt, wenn die Anwendung initiiert wird, das DATABASES
Wörterbuch (das einzige mit default
von den test_settings) zwischengespeichert wird und dann, obwohl ich setting.DATABASES
ändern, der neue Wert ist einfach nicht mehr zugegriffen.
Wie kann ich die Datenbankkonfiguration für einen bestimmten Test richtig überschreiben?