İçeriğe geç

Django ile Veritabanı Dumpı Almak ve Geri Yüklemek

Merhabalar.

Web uygulamaları geliştirirken, bir çok kere farklı projelerde aynı veriyi, tekrarlayan bir yapıda saklama ihtiyacımız ya da veritabanı değişikliği, yeni ortama geçiş gibi işlemler sonucunda halihazırdaki verileri kaybetmeden yeni ortama geçirme ihtiyacımız olmakta.

Bugün Django fixtures yapısına, loaddata ve dumpdata yönetim komutları ile dump alma, dumpı geri yükleme gibi konulara göz atacağız.

Django yönetim komutları hakkında daha fazla bilgi almak isterseniz.

Komutlara geçmeden önce;

Django Fixtures nedir?

Fixtures, Django proje modellerinize başlangıç verisi oluşturmanıza olanak sağlayan, başka bir uygulamada ya da test adımlarında yüklenebilir veritabanı-model çıktılarıdır.

Serializasyon formatı olarak, varsayılan JSON kullanır fakat XML, YAML gibi formatlarda desteklenmektedir. (YAML formatı PyYAML kütüphanesine ihtiyaç duyar.)

Bir fixture oluşturmak için, dumpdata varolan bir fixture’ı yüklemek içinse loaddata komutu kullanılır.


Örnek olması açısından tüm projelerde ortak olarak kullanılabilecek bir adres yapısı oluşturalım. (app ismi address.)

from django.db import models


class Country(models.Model):

    name = models.CharField(max_length=255)

    def __str__(self) -> str:
        return self.name


class City(models.Model):
    country = models.ForeignKey("address.Country", on_delete=models.CASCADE)
    name = models.CharField(max_length=255, unique=True)

    def __str__(self) -> str:
        return self.name


class Township(models.Model):
    city = models.ForeignKey("address.City", on_delete=models.CASCADE)
    name = models.CharField(max_length=255)

    def __str__(self) -> str:
        return self.name

Daha sonrasında ister admin panelinden, ya da shellden biraz veri ekleyin.

Fixture oluşturmak ve dumpdata.

dumpdata komutu aşağıdaki gibi kullanılır ve varolan model verilerini transfer edebilmek için seçilen formata uygun serialize ederek bir çıktı oluşturur.

Genellikle, projeyi tamamiyle yeni bir veritabanına taşımıyorsak auth.Permission, ContentType, admin.LogEntry gibi projeninin tüm modelleri ile doğrudan bir ilişki içinde olan modelleri pas geçmemiz gerekir.

Komut formatı.

$ python manage.py dumpdata --exclude auth.permission --exclude contenttypes.contenttype  --exclude admin.logentry --output your_fixture.json

exclude etmek yerine doğrudan dump alınacak app yada model ismi verebiliriz. Adres uygulamasının  tamamını dump alacak olsa idik;

$ python manage.py dumpdata address --format json --indent 4
[
{
    "model": "address.country",
    "pk": 1,
    "fields": {
        "name": "Türkiye"
    }
},
{
    "model": "address.city",
    "pk": 1,
    "fields": {
        "country": 1,
        "name": "Muğla"
    }
},
{
    "model": "address.township",
    "pk": 1,
    "fields": {
        "city": 1,
        "name": "Bodrum"
    }
}
]

Farklı bir format?

$ python manage.py dumpdata address  --format yaml 
- model: address.country
  pk: 1
  fields:
    name: Türkiye
- model: address.city
  pk: 1
  fields:
    country: 1
    name: Muğla
- model: address.township
  pk: 1
  fields:
    city: 1
    name: Bodrum

–output fixture çıktısın kaydedileceği dosya ismi, –exclude fixture dışında tutulacak olan modellerin tanımlanması sırasında kullanılan komut argümanları.


Fixture geri yüklemek ve loaddata.

Gerekli veriyi export edip fixturelarımızı oluşturduk ve yeni ortama ya da projeye geçmeye hazırız. Fixtureları geriye yüklemek için loaddata komutunu kullanacağız.

Komut formatı;

$ python manage.py loaddata fixture_name

Django loaddata komutu çağrıldığında komuta geçilen fixture ismini her uygulama altındaki fixtures klasöründe arar.

İsterseniz doğrudan bir fixture_pathi belirtebileceğiniz gibi, settings üzerinde FIXTURES_DIRS ‘i Django’nun arama yaparken farklı bir pathide dikkate alması için güncelleyebilirsiniz.

Doğrudan bir fixture_pathi belirtmek;

$ python manage.py loaddata address/legacy_data/legacy_address.json

Nesne sayınıza göre aşağıdaki gibi bir çıktı alabiliyorsanız harika! Modellerinizin dumpını alıp farklı bir ortam yada projeyle başarıyla aktardınız.

Installed 3 object(s) from 1 fixture(s)

Not. Bunun yanında aynı fixture dosyasını tekrar tekrar yüklemeye çalıssanızda, herhangi bir row datasını değiştirmediğiniz sürece Django mükerrer bir kayıt oluşturmayacaktır. Bir row değişikliği var ise sadece yeni eklenen row veritabanına kayıt edilecektir.


Fixturelar’ın test sırasında kullanımı.

Kişisel olarak pek tercih etmiyor ve model_bakery kullanıyor olsamda; veri taşımanın yanında, fixturelar test yazma sürecinde test boyunca kullanılacak datayı oluşturmak için de kullanılabilir.

Örneğin;

from django.test import TestCase

from address.models import City, Country, Township


class AddressTestCase(TestCase):

    fixtures = ["your_fixture_name", "another_fixture"]

    def test_name_mugla_in_cities(self):
        city_names = City.objects.values_list("name", flat=True)
        self.assertIn("Muğla", city_names)

    def test_country_count(self):
        self.assertEqual(Country.objects.count(), 1)

Excited Season 2 GIF by The Office

 

Sonuç.

Veriyi taşımak uygulama geliştirme süreçlerinde önemli bir adım.

Bugün Django ile bu sürece bir çözüm getirmeye göz attık. Tabii ki tek çıkar yol bu değil. Örneğin bir data migration da yazabilirsiniz. Bu tamamen projenizin gereklilikleri doğrultusunda şekillenecektir.

Bu konuda ya da yazı içerisinde geçen anahtar kelimeler hakkında okumaya devam etmek isterseniz;

Django Fixtures Dökümantasyonu.

Django Data Migration blog postum.

Test datası oluşturmanın çok daha kolay ve programatik yolu model_bakery.

İyi günler!

 

Tarih:Blog

İlk Yorumu Siz Yapın

Bir cevap yazın

E-posta hesabınız yayımlanmayacak.

Göster
Gizle