Je connais l'objet curseur dans Django. Existe-t-il un autre moyen préféré d'exécuter du SQL brut dans les migrations? Je veux introduire le partitionnement postgresql pour l'une de mes tables de modèles. La logique de partition est un tas de fonctions et de déclencheurs qui doivent être ajoutés à la base de données lors de la configuration que j'aimerais automatiser.
La meilleure façon de le faire est d'utiliser RunSQL:
Migrations contient la classe RunSQL. Pour faire ça:
./manage.py makemigrations --empty myApp
operations = [ migrations.RunSQL('RAW SQL CODE') ]
Comme Nathaniel Knight l'a mentionné, RunSQL
accepte également un paramètre reverse_sql
Pour inverser la migration. Voir la documentation pour plus de détails
La façon dont j'ai résolu mon problème au départ était d'utiliser le signal post_migrate
Pour appeler un curseur pour exécuter mon SQL brut.
Ce que je devais ajouter à mon application était le suivant:
dans le __init__.py
de myApp ajoutez:
default_app_config = 'myApp.apps.MyAppConfig'
Créez 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.'
Désormais, tous les 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.
Je recommanderais Django-migrate-sql-deux https://pypi.org/project/Django-migrate-sql-deux/
De cette façon, vous pouvez gérer des objets de base de données comme des vues, des fonctions, des déclencheurs de manière déclarative comme des modèles dans Django. Ensuite, vous devez générer des modifications dans Django migrations via makemigrations
. Et les appliquer via migrate
. Ainsi, le flux de développement et de déploiement est assez identique.
Ce serait génial si Django aurait ce système pour les "modèles" SQL bruts et gérerait automatiquement les migrations et les dépendances dans les commandes makemigrations
et migrate
comme Django-migrate-sql-deux.