Aller simple :
Le meilleur moyen que j'ai trouvé pour le faire est d'utiliser RunSQL :
Migrations contient la classe RunSQL. Pour ce faire :
./manage.py makemigrations --empty myApp
- modifiez le fichier de migration créé pour inclure :
operations = [
migrations.RunSQL('RAW SQL CODE')
]
Comme Nathaniel Knight l'a mentionné, RunSQL
accepte également un reverse_sql
paramètre pour inverser la migration. Voir la documentation pour plus de détails
Une autre façon
La façon dont j'ai résolu mon problème au départ était d'utiliser le post_migrate
signal pour appeler un curseur pour exécuter mon SQL brut.
Voici ce que j'ai dû ajouter à mon application :
dans le __init__.py
de myApp ajouter :
default_app_config = 'myApp.apps.MyAppConfig'
Créer un fichier 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)
Nouveau fichier 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.'
Maintenant sur chaque manage.py syncdb
ou manage.py migrate
cette fonction est appelée. Assurez-vous donc qu'il utilise CREATE OR REPLACE
et IF NOT EXISTS
. Il peut donc gérer les fonctions existantes.