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)
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!
İlk Yorumu Siz Yapın