Frage

Ich habe einige Codes, die Ursachen syncdb werfen einen Fehler wirft (weil es versucht, das Modell zuzugreifen, bevor die Tabellen erstellt werden).

Gibt es eine Möglichkeit, den Code zu verhindern, auf syncdb läuft? so etwas wie:

if not syncdb:
    run_some_code()

Danke:)

Bearbeiten : PS - Ich dachte über das post_init Signal mit ... für den Code, der die db zugreift, ist das eine gute Idee

Mehr Infos

Hier finden Sie einige weitere Informationen wie gewünscht:)

Ich habe in diesen ein paar Mal laufen, zum Beispiel ... Ich war auf django-cron Hacking und bestimmen es notwendig, dass es nicht die bestehenden Arbeitsplätze zu machen, wenn Sie django laden (weil es alle installierten Anwendungen sucht Arbeitsplätze und fügt sich auf Last sowieso).

So habe ich den folgenden Code an die Spitze der __init__.py-Datei:

import sqlite3

try:
        # Delete all the old jobs from the database so they don't interfere with this instance of django
        oldJobs = models.Job.objects.all()
        for oldJob in oldJobs:
                oldJob.delete()
except sqlite3.OperationalError:
        # When you do syncdb for the first time, the table isn't 
        # there yet and throws a nasty error... until now
        pass

Aus offensichtlichen Gründen ist dieser Mist. es ist gebunden an SQLite und ich bin es gibt bessere Orte diesen Code zu setzen (dies ist nur, wie ich bei der Ausgabe geschehen), aber es funktioniert.

Wie Sie sehen können die Fehler, den Sie erhalten, ist Operational Error (in SQLite) und der Stack-Trace sagt etwas entlang der Linien von „Tabelle django_cron_job nicht gefunden“

Lösung

Am Ende war das Ziel, auf einige Codes ausführen, bevor alle Seiten geladen wurden .

Dies kann durch die Ausführung in der urls.py Datei ausgeführt werden, da sie importiert werden muss, bevor eine Seite bedient werden kann (natürlich).

Und ich war in der Lage, das hässlich Try / außer Block zu entfernen :) Gott danken (und S. Lott)

War es hilfreich?

Lösung

„bearbeiten: PS - Ich dachte über das post_init Signal mit ... für den Code, der die db zugreift, ist das eine gute Idee“

Nie.

Wenn Sie Code haben, der das Modell zugreift, bevor die Tabellen erstellt werden, Sie haben große, große Probleme. Du bist wahrscheinlich etwas falsch zu tun.

Normalerweise laufen Sie syncdb etwa einmal. Die Datenbank wird erstellt. Und Ihre Web-Anwendung verwendet die Datenbank.

Manchmal haben Sie eine Designänderung, löschen und die Datenbank neu erstellen. Und dann Ihre Web-Anwendung verwendet diese Datenbank für eine lange Zeit.

Sie (in der Regel) nicht brauchen Code in einem __init__.py Modul. Sie sollten (fast) nie ausführbaren Code, der in einem __init__.py Modul eigentliche Arbeit der Fall ist. Es ist sehr, sehr selten, und unpassend für Django.

Ich bin mir nicht sicher, warum Sie mit __init__.py sind durcheinander, wenn Django Cron sagt, dass Sie Ihren Zeitplan in urls.py machen.


Bearbeiten

Clearing Aufzeichnungen sind eine Sache.

Herumspielen mit __init__.py und Django-cron des base.py sind klar völlig falsche Wege, dies zu tun. Wenn es so kompliziert ist, du tust es falsch.

Es ist unmöglich zu sagen, was Sie zu tun versuchen, aber es sollte trivial sein.

Ihre urls.py erst nach syncdb laufen und schließlich des ORM Material richtig konfiguriert und gebunden wurde.

Ihre urls.py könnten zum Beispiel einige Zeilen löschen und dann einige Zeilen zu einer Tabelle hinzufügen. An diesem Punkt sind alle syncdb Fragen sind aus dem Weg.

Warum haben Sie nicht Ihre Logik in urls.py?

Andere Tipps

Code, der die Modelle zuzugreifen versucht, bevor sie recht erstellt sind, können viel existieren nur auf Modulebene; es würde ausführbaren Code ausgeführt werden, wenn das Modul importiert wird, wie Ihr Beispiel zeigt. Dies ist, wie Sie erraten haben, ist der Grund von syncdb ausfällt. Es wird versucht, das Modul zu importieren, aber der Akt der das Modul Import verursacht Application-Level-Code auszuführen; ein „Nebeneffekt“, wenn man so will.

Der Wunsch Modul importiert zu vermeiden, die Nebenwirkungen verursachen ist so stark in Python, dass die if __name__ == '__main__': Konvention für ausführbare Python-Skripte alltäglich geworden ist. Wenn nur eine Code-Bibliothek Laden verursacht Ausführen eine Anwendung zu starten, Kopfschmerzen ergeben: -)

Für Django-Anwendungen, wird dies mehr als ein Kopfschmerz. Betrachten wir die Wirkung haben oldJob.delete() jedes Mal das Modul ausgeführt wird importiert. Es mag scheinen, wie es nur ein einziges Mal ausgeführt wird, wenn Sie mit dem Django-Entwicklungsserver laufen, aber in einer Produktionsumgebung wird es sehr oft ausgeführt werden soll. Wenn Sie Apache verwenden, zum Beispiel, wird Apache häufig um mehrere Kindprozesse warten Feuer auf Anfragen zu behandeln. Als lang laufender Server fortschreitet, wird Ihre Django App jedes Mal ein Handler für Ihren Webserver gegabelt ist Bootstrap erhalten, was bedeutet, dass das Modul importiert werden und delete() wird mehrmals, oft unvorhersehbar aufgerufen werden. Ein Signal wird nicht helfen, leider, da das Signal auch jedes Mal ein Apache-Prozess initialisiert wird ausgelöst werden könnte.

Es ist nicht, btw, nur einen Webserver, der den Code versehentlich ausführen verursachen könnte. Wenn Sie Tools wie epydoc verwenden, zum Beispiel werden sie Ihren Code importieren API-Dokumentation zu generieren. Dies wiederum würde dazu führen, dass die Anwendungslogik der Ausführung beginnen, das ist offensichtlich ein unerwünschter Nebeneffekt nur eine Dokumentation Parser ausgeführt wird.

Aus diesem Grunde Bereinigungscode wie dies entweder am besten durch einen Cron-Job behandelt, die für veraltete Jobs in regelmäßigen Abständen sieht und die DB bereinigt. Diese benutzerdefinierte Skript kann auch manuell ausgeführt werden, oder durch eine beliebiges Verfahren (zum Beispiel bei einem Einsatz oder als Teil Ihrer Unit-Test setUp() Funktion eines sauberen Testlauf zu gewährleisten). Egal, wie Sie es tun, der wichtige Punkt ist, dass Code wie dies sollte immer ausgeführt werden explizit , anstatt implizit als Ergebnis die Quelldatei zu öffnen.

Ich hoffe, das hilft. Ich weiß, dass es nicht einen Weg bereitstellt, um zu bestimmen, ob syncdb läuft, aber das syncdb Problem wird auf magische Weise verschwinden, wenn Sie Ihre Anwendung Django Design mit Produktionsbereitstellung im Auge behalten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top