Veritabanı sorgularında yorumlama ve kümeleme.

02/2012

Django'nun veritabanı katmanı size basit sorgular yapma imkanı tanıdığı gibi, çeşitli yorumlama (annotation) ve kümeleme (aggregation) işlemleri yapmanıza da imkan sağlıyor. Söz gelimi bir kullanıcının gelir giderini tuttuğumuz transaction adında bir modelimiz olduğunu farzedelim.

from django.contrib.auth.models import User

class Transaction(models.Model):
    user = models.ForeignKey(User)
    balance = models.IntegerField()
    description = models.CharField(max_length=255)</pre>

Şimdi de x kullanıcısı için bir kaç adet işlem oluşturalım:

... : from django.contrib.auth.models import User
... : user_x = User.objects.get(...)
... : Transaction.objects.create(
... :     user=user_x,
... :     balance=200,
... :     description="Cebimde 200 lira var")
... :
... : Transaction.objects.create(
... :     user=user_x,
... :     balance=-15,
... :     description="Taksi parası")
... : 
... : Transaction.objects.create(
... :     user=user_x,
... :     balance=-120,
... :     description="Mutfak alışverişi")</pre>

Kullanıcı 3 adet işlem yaptı. Şu an kayıtlı olan bütün transaction objelerinden yola çıkarak ve kümeleme metodunu kullanarak kullanıcının toplam para durumuna bakalım.

... : from django.db.models import Sum
... : Transaction.objects.all().aggregate(total=Sum('balance'))
... : {'total': 65 }

Gördüğünüz gibi bütün balance değerlerini toplayarak bize (+200 - 15 - 120 = 65) sonucunu gönderdi. Eğer istersek yorumlama özelliğini kullanarak kullanıcıları direkt olarak balans durumları ile birlikte alabiliriz.

... : user_x = User.objects.get(...).annotate(\
... :     balance=Sum("transaction__balance"))
... : user_x.balance
... : 65

Burada yaptığımız şey Django'ya şunu söylemek oldu:

User nesnesini al, ancak transaction içerisindeki balance değerlerini toplayıp, balance adında yeni bir kolon olarak ekle.

Tabi burada sadece Sum fonksiyonu ile sınırlı değilsiniz. Count, Max, Avg gibi bir çok metod mevcut. Daha fazla bilgi için şuraya bakabilirsiniz:

https://docs.djangoproject.com/en/dev/topics/db/aggregation/