W jedną stronę:
Najlepszym sposobem, jaki znalazłem, aby to zrobić, jest użycie RunSQL:
Migracje zawiera klasę RunSQL. Aby to zrobić:
./manage.py makemigrations --empty myApp
- edytuj utworzony plik migracji, aby uwzględnić:
operations = [
migrations.RunSQL('RAW SQL CODE')
]
Jak wspomniał Nathaniel Knight, RunSQL
akceptuje również reverse_sql
parametr do cofania migracji. Szczegóły znajdziesz w dokumentacji
Inny sposób
Sposób, w jaki początkowo rozwiązałem mój problem, polegał na użyciu post_migrate
sygnał do wywołania kursora w celu wykonania mojego surowego SQL.
To, co musiałem dodać do mojej aplikacji, to:
w __init__.py
dodania mojej aplikacji:
default_app_config = 'myApp.apps.MyAppConfig'
Utwórz plik 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)
Nowy plik 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.'
Teraz w każdej manage.py syncdb
lub manage.py migrate
ta funkcja jest nazywana. Upewnij się więc, że używa CREATE OR REPLACE
i IF NOT EXISTS
. Dzięki temu może obsługiwać istniejące funkcje.