2016-01-17 17 views
5

Ich bin ziemlich sicher mit Django, habe mich aber bis vor kurzem hauptsächlich auf generierte Migrationen verlassen. Ich schrieb eine kleine benutzerdefinierte Migration, und kurz nachdem mein CI anfing, sich über Timeouts zu beschweren, endete es damit, dass es etwas mit den Migrationen von Django während der Bereitstellung zu tun hatte.Django-Migration wird getötet

Zuerst konnte ich dieses Problem beheben, aber ich weiß nicht, was ich getan habe (wenn überhaupt), das es repariert hat. Das Problem scheint mit einem benutzerdefinierten Code zusammenzuhängen, den ich für eine bestimmte Migration eingegeben habe. Hier ist, was ich weiß:

  • Anfangs war alles in Ordnung, aber die Wanderungen begann eine wirklich lange Zeit zu laufen (relativ) nach meinem eigenen Code hinzufügen. Ungefähr 10 Sekunden zur Zeit.
  • Es funktioniert manchmal. dh. Wenn ich die Migration zehn Mal über die Befehlszeile ausfühle, funktioniert sie manchmal und manchmal schlägt sie fehl.

Die Ausgabe lautet wie folgt (app Namen bearbeitet out):

[[email protected] myapp]$ ./manage.py migrate 
Operations to perform: 
    Apply all migrations: myapp1, myapp2, myapp3, myapp4 
Running migrations: 
Killed 
  • Zuerst dachte ich, es war, weil ich RunPython bin mit einer Python-Funktion, die kopierte Daten zwischen zwei Feldern laufen, bevor Löschen eines der Felder Die Dokumentation rät davon ab, PostgreSQL zu verwenden, aber gibt es dafür einen besseren Weg?
  • Das Geschäftsszenario hier ist, dass ich ein boolesches Feld hatte, das ich zu einer Reihe von Optionen wechseln musste (CharField mit options). Der Code prüft, ob der Boolesche Wert wahr ist, und legt den korrekten Wert für das Zeichenfeld fest. Ich habe das zweimal gemacht. Das erste Mal endete die Arbeit schließlich, aber ich habe es noch nicht in einer anderen Datenbank getestet.

Dies ist die Migration (app Namen bearbeitet out):

from __future__ import unicode_literals 

from django.db import migrations 

def fix_consulting(apps, schema_editor): 
    my_model = apps.get_model("myapp", "MyModel") 
    for m in my_model._default_manager.all(): 
     if m.consulting: 
      m.detail = "CONSLT" 
      m.save() 


class Migration(migrations.Migration): 

    dependencies = [ 
     ('myapp', '0024_auto_20160117_1113'), 
    ] 

    operations = [ 
     migrations.RunPython(fix_consulting,atomic=False), 
    ] 

Meine Gedanken:

  • Vielleicht ist der Code, den ich hier bin Schreiben zu lange dauert zu laufen? Es gibt weniger als einhundert Modelle in der Datenbank, also weiß ich nicht, warum die fix_consulting Funktion so lange dauern würde.

  • Wenn ich Print-Anweisungen am Anfang von fix_consulting hinzufügen, werden sie nur manchmal ausgeführt und andere Male getötet. Wie es aussieht, habe ich lief es 6-8 mal und es jedes Mal getötet wurde, aber an verschiedenen Punkten

Weitere Informationen: - Verwendung von Django 1.9 - Verwenden von PostgreSQL 9.4.4 - Fehler tritt meist auf CentOS, aber auch OSX

+0

Es ist möglich, dass das Gerät nur nicht in der Lage ist um die von 'all' abgerufenen Daten zu speichern, könnte es sein, dass die Änderung der gesamten Schleife zu' my_model._default_manager.filter (consulting = True) .update (detail = "CONSLT") das Problem beheben könnte ... ich würde Sei glücklich, dies zu einer Antwort zu machen, wenn ich richtig bin – Sayse

+1

Ich gebe diesem einen Schuss! Es ist ein Server mit einer ziemlich kleinen Menge an Speicher. –

+1

Sie sind richtig! Der Fehler war zweifach. Sobald ich es zu dem Code änderte, den Sie zur Verfügung stellten, enthüllte es einen anderen Fehler, der ziemlich leicht aufgelöst wurde, weil er mir tatsächlich eine Stapelspur gab. Vielen Dank! Mach weiter und füge die Antwort hinzu. –

Antwort

7

Ich glaube, Ihr Problem wurde durch die Menge der Daten verursacht, die Sie bei Verwendung all zwischenspeichern müssen, da dies alle Instanzen eines Objekts zurückgibt, daher können Sie die Filterung für eine Datenbank tun Bevor Sie die Objekte zurückgeben, müssen Sie nur die Werte eines Feldes ändern. Dies können Sie auch auf Datenbankebene tun. Alles in allem wird dies Ihren Code wie folgt ändern.

def fix_consulting(apps, schema_editor): 
    my_model = apps.get_model("myapp", "MyModel") 
    my_model._default_manager.filter(consulting=True).update(detail="CONSLT") 

Dies setzt die Speicherverwaltung Verantwortlichkeiten auf der Datenbank, die Ihr Problem zu lösen scheint.

vorwärts gehen, würde ich empfehlen, immer unten zu filtern versuchen, was von einem db nur zurückgeführt wird, dass die tatsächlich benötigt wird (sein, dass durch Spleißen oder Filterung)

Verwandte Themen