Django data migrationlar
Sep 9, 2017 · 2 minute read · Commentsprogrammingpython
Django migrationlar Django’nun beni kendine hayran bırakan özelliklerinden biri olduğunu çok rahat söyleyebilirim. Bir satır bile SQL yazmadan database tablolarında değişikliklik yapabiliyorum. Henüz DB migrationlarını Django kadar zahmetsiz ve temiz yöneten herhangi bir dille yazılmış bir framework göremedim. Cansın Django :)
Bazı zamanlar oluyorki modellerde yaptığımız değişikliklerden ötürü bir migration oluşturduğumuzda bu migrationa yeni eklemeler yapmamız veyada bu migrationdan ötürü eski data üzerinde işlemler yapmamız gerekebiliyor.
Şimdi örnek bir senaryo üzerinden custom migration nasıl yazılır ondan bahsetmeye çalışacağım.
Şuan üzerinde çalıştığım projeyi ilk geliştirmeye başladığımızda ilk olarak gelir-gider takibi gibi olmazsa olmaz özellikleri geliştirdik. Daha sonra muhasebe modülünü geliştirdik. Muhasebe modülünü de geliştirdiğimizde artık bir gelir ve gider oluştuğunda otomatik olarak muhasebe fişi de oluşuyordu. Fakat muhasebe modülü geliştirilmeden önce oluşmuş olan gelir ve giderler için muhasebe fişi oluşturmamız gerekiyordu. Bunun için bir custom migration yazdık ve bu migrationla daha önceden oluşmuş olan bütün gelir giderler için fişlerini oluşturduk.
RunPython kullanımı
RunPython
ile migration içerisinde python fonksiyonu çalıştırabiliyoruz.
# Custom migration dosyasi ornegi:
from __future__ import unicode_literals
from django.db import migrations
def forwards_func(apps, schema_editor):
AccountingSlip = apps.get_model("accounting", "AccountingSlip")
# migration calistiginda calisir
AccountingSlip.objects.create(...)
def reverse_func(apps, schema_editor):
# migration'i geri aldigimizda calisir.
AccountingSlip = apps.get_model("accounting", "AccountingSlip")
AccountingSlip.objects.all().delete()
class Migration(migrations.Migration):
dependencies = [...]
operations = [
# Custom migration
migrations.RunPython(forwards_func, reverse_func, atomic=True),
]
RunPython
kullanırken bilmeniz gereken bir nokta RunPython
‘un defaultta migration fonksiyonunun transaction bloğu içerisinde çalışmadığıdır. Fonksiyonu transaction bloğu içinde çalıştırmak için RunPython
fonksiyonunu çalıştırırken atomic=True
verebilirsiniz.
Migration geri alındığında ekstra herhangi bir işlem yapılmayacaksa, reverse_func
yerine RunPython.noop
kullanabilirsiniz.
RunSQL kullanımı
RunSQL
migration içerisinde custom SQL çalıştırmamıza olanak sağlar.
operations = [
migrations.RunSQL(["UPDATE mytable set foo=bar"], RunSQL.noop),
],
İhtiyacınıza göre RunPython
veyada RunSQL
kullanabilirsiniz. Ben sql ile kasmak yerine custom migrationları python ile yazmayı tercih ediyorum.
Bu yazıyı yazdığımda Django 1.11 kullanıyordum.