Ответ 1
Один из способов:
Лучший способ, которым я нашел это, - использовать RunSQL:
Миграции содержат класс RunSQL. Для этого:
-
./manage.py makemigrations --empty myApp
- отредактируйте созданный файл миграции, чтобы включить:
operations = [
migrations.RunSQL('RAW SQL CODE')
]
Как упоминал Натаниел Найт, RunSQL
также принимает параметр reverse_sql
для изменения миграции. Подробнее см. в документах
Другой способ
Как я решил свою проблему изначально, использовал сигнал post_migrate
для вызова курсора для выполнения моего необработанного SQL.
Что мне нужно было добавить в мое приложение:
в __init__.py
myApp добавьте:
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
. Таким образом, он может обрабатывать существующие функции.