Еднопосочен:
Най-добрият начин, който открих, е да използвам RunSQL:
Миграциите съдържат класа RunSQL. За да направите това:
./manage.py makemigrations --empty myApp
- редактирайте създадения файл за миграции, за да включите:
operations = [
migrations.RunSQL('RAW SQL CODE')
]
Както Nathaniel Knight спомена, RunSQL
също приема reverse_sql
параметър за обръщане на миграцията. Вижте документите за подробности
Друг начин
Начинът, по който реших проблема си първоначално, беше с помощта на post_migrate
сигнал за извикване на курсор за изпълнение на моя необработен SQL.
Това, което трябваше да добавя към приложението си, беше следното:
в __init__.py
на myApp add:
default_app_config = 'myApp.apps.MyAppConfig'
Създайте файл 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)
Нов файл 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.'
Сега на всеки manage.py syncdb
или manage.py migrate
тази функция се нарича. Затова се уверете, че използва CREATE OR REPLACE
и IF NOT EXISTS
. Така че може да обработва съществуващи функции.