2015-07-29 12 views
17

Ich bin mir des Cursor-Objekts in Django bewusst. Gibt es eine andere bevorzugte Möglichkeit zum Ausführen von Raw SQL in Migrationen? Ich möchte die Postgresql-Partitionierung für eine meiner Modelltabellen einführen. Die Partitionslogik besteht aus einer Reihe von Funktionen und Triggern, die bei der Einrichtung, die ich automatisieren möchte, zur Datenbank hinzugefügt werden müssen.Wie führe ich rohe SQL in einer Django-Migration aus

Antwort

29

One way:

Der beste Weg, dies zu tun, ich gefunden RunSQL mit:

Migrations enthält die RunSQL Klasse. Um dies zu tun:

  1. ./manage.py makemigrations --empty myApp
  2. bearbeitet die erstellt Migrationen Datei enthalten sein:

operations = [ migrations.RunSQL('RAW SQL CODE') ]

Als Nathaniel Ritter erwähnt, RunSQL akzeptiert auch einen reverse_sql Parameter für die Migration rückgängig zu machen. See the docs for details

Ein anderer Weg

Die Art, wie ich mein Problem zunächst gelöst wurde das post_migrate Signal mit einem Cursor nennen meine rohen SQL auszuführen.

Was ich meine App hinzuzufügen hatte, war dies:

im __init__.py von myApp hinzufügen:

default_app_config = 'myApp.apps.MyAppConfig' 

Erstellen Sie eine Datei apps.py:

from django.apps import AppConfig 
from django.db.models.signals import post_migrate 
from myApp.db_partition_triggers import create_partition_triggers 


class MyAppConfig(AppConfig): 
    name = 'myApp' 
    verbose_name = "My App" 

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

Neue Datei db_partition_triggers.py:

from django.db import connection 


def create_partition_triggers(**kwargs): 
    print ' (re)creating partition triggers for myApp...' 
    trigger_sql = "CREATE OR REPLACE FUNCTION...; IF NOT EXISTS(...) CREATE TRIGGER..." 
    cursor = connection.cursor() 
    cursor.execute(trigger_sql) 
    print ' Done creating partition triggers.' 

Nun wird auf jeder manage.py syncdb oder manage.py migrate diese Funktion aufgerufen. Stellen Sie also sicher, dass CREATE OR REPLACE und IF NOT EXISTS verwendet werden. So kann es mit bestehenden Funktionen umgehen.

+0

Gibt es eine Möglichkeit, Rückwärtsmigration für Suctom SQL hinzuzufügen? – DataGreed

+0

Sie sollten Ihre Notiz über RunSQL wirklich nach oben verschieben. Es ist absolut der beste Weg, dies zu tun ... –

+0

@DataGreed Nicht sicher, ob Sie immer noch wissen möchten, aber Sie können eine zweite SQL-Zeichenfolge übergeben, um als die umgekehrte SQL verwendet werden. – LarrikJ