2017-04-13 1 views
4

Ich dachte, es gab eine einfache Antwort auf diese in den letzten Versionen von Django, aber ich kann es nicht finden.Django: Ausführen von Code bei jedem Start, aber nachdem die Datenbank migriert wurde

Ich habe Code, der die Datenbank berührt. Ich möchte, dass es jedes Mal läuft, wenn Django startet. Ich scheine zwei Möglichkeiten zu haben:

Option 1.AppConfig.ready() - das funktioniert aber läuft auch vor Datenbanktabellen erstellt wurden (das heißt während des Tests oder wenn neu initialisiert die App ohne Daten). Wenn ich diese verwenden muss ich mehrere Arten von Ausnahmen und erraten, fangen, dass die Ursache ist eine leere db:

def is_db_init_error(e, table_name): 
    return ("{}' doesn't exist".format(table_name) in str(e) or 
      "no such table: {}".format(table_name) in str(e) 
    ) 

try: 
    # doing stuff 
except Exception as e: 
    if not is_db_init_error(e, 'foo'): 
     raise 
    else: 
     logger.warn("Skipping updating Foo object as db table doesn't exist") 

Option 2. Verwendung post_migrate.connect(foo_init, sender=self) - aber das nur läuft, wenn ich eine Migration tun.

Option 3. Der alte Weg - nennen es von urls.py - ich für Option 2 so weit Sachen wie diese aus urls.py und ich dachte AppConfig war der einzig wahre Weg

Ich habe angesiedelt halten wollte - Ich mag nicht den stinkigen Versuch/außer Sachen in Option 1 und Option 3 Bugs mich als urls.py wird zu einer Müllhalde.

Allerdings stolpert mich Option 2 oft, wenn ich lokal entwickle - ich muss daran denken, Migrationen immer dann auszuführen, wenn ich möchte, dass mein Init-Code läuft. Dinge wie das Herunterfahren einer Produktionsdatenbank oder ähnlichem verursachen oft Probleme, weil Migrationen nicht ausgelöst werden.

+0

Ich habe noch nicht das selbst ausprobiert, aber man konnte die manage.py Datei überschreiben – dentemm

Antwort

1

würde ich vorschlagen, das connection_created Signal, das ist:

gesendet, wenn die Datenbank-Wrapper die erste Verbindung zur Datenbank macht. Dies ist besonders nützlich, wenn Sie Post- Verbindungsbefehle an das SQL-Backend senden möchten.

So wird der Signalcode ausgeführt, wenn die App zu Beginn des Anwendungszyklus eine Verbindung zur Datenbank herstellt.

Es wird auch innerhalb einer mehr Datenbank-Konfiguration arbeiten und trennt auch die von der App bei der Initialisierung gemacht Verbindungen:

Verbindung
Die Datenbankverbindung, die geöffnet wurde. Dies kann in einer Konfiguration mit mehreren Datenbanken verwendet werden, um die Verbindungssignale von verschiedenen Datenbanken zu unterscheiden.


Hinweis:
Es ist unklar, aber sehr wahrscheinlich, dass das connection_created Signal wird ausgeführt, wenn Sie die Migration machen, und wenn Sie auch wandern.
Das heißt, Sie können in Erwägung ziehen, eine Kombination von post_migrate und connection_created Signale zu verwenden, während Sie innerhalb Ihrer AppConfig.ready() überprüfen, ob eine Migration (z. B.Flagge die Aktivierung eines post_migrate Signal):

from django.apps import AppConfig 
from django.db.models.signals import post_migrate, connection_created 

migration_happened = false 

def post_migration_callback(sender, **kwargs): 
    ... 
    migration_happened = true 


def init_my_app(sender, connection): 
    ... 


class MyAppConfig(AppConfig): 
    ... 

    def ready(self): 
     post_migrate.connect(post_migration_callback, sender=self) 

     if !migration_happened: 
      connection_created.connect(init_my_app, sender=self) 

Viel Glück :)

Verwandte Themen