Как выполнить необработанный SQL в миграции django

Мне известен объект курсора в Django. Есть ли другой предпочтительный способ выполнения сырого SQL при миграции? Я хочу ввести разбиение postgresql для одной из моих таблиц моделей. Логика раздела представляет собой набор функций и триггеров, которые необходимо добавить в базу данных при настройке, которую я хотел бы автоматизировать.

Ответы

Ответ 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. Таким образом, он может обрабатывать существующие функции.