İçeriğe geç

Django Model Save update_fields

Django ORM, veritabanı üzerindeki kayıtları nesne yönelimli programlama paradigmasına dayanarak nesneleştiren, oluşturulan nesneleri ve ön tanımlı metodlarını kullanarak veritabanı operasyonlarını yapmanızı, raw SQL’ den soyutlanmanızı sağlayan güçlü ve yardımcı bir araç.

Django ORM fazlasıyla gelişmiş ve projelerin çoğunda raw SQL yazmak zorunda kalmasakta bir kaç noktada performans iyileştirmeleri için başvurabileceğimiz yollar var. Bugün de o yollardan biri olan save metodunda update_fields kullanımına göz atacağız.

Basit bir model.

Aşağıdaki gibi çalışmamızı örnekleyebileceğimiz bir model kurgulayalım.

from django.db import models

class Entity(models.Model):

    name = models.CharField(max_length=255)
    body = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)
    modified_at = models.DateTimeField(auto_now=True)

Save metodu nasıl çalışır?

Veritabanı üzerinde bulunan bir nesnenin herhangi bir fieldi aşağıdaki gibi güncelleme işlemine tabi tutulursa,

entity = Entity.objects.first()
entity.name = "Entity name updated for blog post."
entity.save()

bu işlemin sonucunda oluşan ve çalıştırılan SQL çıktısı aşağdaki gibi olacaktır. (Sqlite)

UPDATE "example_entity"
   SET "name" = 'Entity name updated for blog post.',
       "body" = 'lorem ipsum dolor sit amet.',
       "created_at" = '2022-12-07 18:29:10.970669',
       "modified_at" = '2022-12-07 19:12:40.642565'
 WHERE "example_entity"."id" = 1

SQL çıktılarını kolayca almak için django_extensions paketini kullanabilirsiniz.

save metodu varsayılan olarak, tek bir field güncellenmiş olsa dahi veritabanına var olan fieldların değerlerinin tamamını tekrar yazar.

Çok fazla update transaction alan veya 3-4 field yerine çok daha fazla veri barınan bir modeliniz varsa bu işlem bir zaman sonra veritabanı tarafında size performans maliyeti olarak dönecektir.

Bunun önüne geçmek içinse, yine Django modellerinin varsayılan save metodunda sağladığı update_fields parametresini kullanabiliriz.

update_fields.

Veritabanında, hangi alanların güncelleneceğini açıkca belirtmek için update_fields parametresini geçelim.

entity = Entity.objects.first()
entity.name = "Entity name changed for update_fields usage."
entity.save(update_fields=["name"])

Oluşturulan ve çalıştırılan SQL çıktısı (Sqlite)

UPDATE "example_entity"
   SET "name" = 'Entity name changed for update_fields usage.'
 WHERE "example_entity"."id" = 1

Sadece tek bir field için güncelleme sağlayacak olan SQL çıktısı oluşturuldu ve çalıştırıldı. Bu işlem bize verimlilik sağlayacaktır.

Birden fazla alanı güncelleyecek ve yine fieldların tamamını tekrar yazmak istemiyorsanız, update_fields = [“field1”, “field2”] şeklinde kullanabilirsiniz.

Son olarak burası çokomelli 🙂

Eğer modeli dikkatlice incelediyseniz, modified_at isminde auto_now ile doldurulan bir field var ve nesne güncellendiği halde değeri değişmedi 🤔

Bunun sebebi, save metoduna açıkca update_fields parametresi paslandığında, sadece paslanan fieldlar için pre_save işlemleri yapılır. pre_save işlemleriyse bir fieldin yazılmadan önce hesaplanması için kullanılır. Örneğin date/datetimefield i auto_now ile oluşturuyorsanız, update_fields üstünde açıkta belirtilmediği için hesaplanmayacaktır.

entity.name = "for pre saving"
entity.save(update_fields=["name", "modified_at"])
UPDATE "example_entity"
   SET "name" = 'for pre saving',
       "modified_at" = '2022-12-07 19:56:47.145886'
 WHERE "example_entity"."id" = 1

Yukarıdaki modeldeki gibi bir oto kullanımınız varsa, bunu göz ardı etmemeniz gerekmekte.

Bunun yanında update_fields = [] gönderilecek olursa, Django herhangi bir veriyi kaydetmeyecek gelen veri kaybolacaktır. Generic bu değişkeni oluşturup save metoduna geçiren bir logic varsa buna da dikkat etmenizde fayda var.


Django modelleri hakkında daha fazla bilgi için dökümantasyon linkiyse burada.

İyi akşamlar!

Tarih:Blog

Tek Yorum

  1. Anonim Anonim

    her sabah uykulu, uyanmak icin bir bardak kahveye ihtiyaci olan; ‘tatsiz’ ve ‘hic hos degil’ kelimelerini kullanmayi seven django’nun sakarya temsilcisi egehan 😀 bu cokomelli yazi icin cok tesekkurler!

Bir cevap yazın

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

Göster
Gizle