PostgreSQL
 sql >> डेटाबेस >  >> RDS >> PostgreSQL

मैं Django में एक मॉडल के लिए दैनिक रैंकिंग कैसे रिकॉर्ड करूं?

मैं कुछ इसी तरह का सुझाव दूंगा जो e4c5 सुझाए गए के समान है। , लेकिन मैं यह भी करूंगा:

  • रैंक की तारीख पर एक इंडेक्स जेनरेट करें ताकि किसी एक दिन में सभी रैंक प्राप्त करने के लिए अनुकूलित किया जा सके।

  • दिनांक और छात्र को unique_together as के रूप में चिह्नित करें . यह एक ही छात्र के लिए एक ही तिथि पर दो रैंक दर्ज करने की संभावना को रोकता है।

मॉडल इस तरह दिखाई देंगे:

from django.db import models

class Grade(models.Model):
    pass  # Whatever you need here...

class Student(models.Model):
    name = models.CharField(max_length=20)
    grade = models.ForeignKey(Grade)

class Rank(models.Model):

    class Meta(object):
        unique_together = (("date", "student"), )

    date = models.DateField(db_index=True)
    student = models.ForeignKey(Student)
    value = models.IntegerField()

एक पूर्ण आवेदन में मैं Grade पर कुछ विशिष्टता बाधाओं की भी अपेक्षा करता हूं और Student लेकिन प्रश्न में प्रस्तुत समस्या इन मॉडलों के बारे में पर्याप्त विवरण प्रदान नहीं करती है।

फिर आप हर दिन cron . के साथ एक कार्य चला सकते हैं या जो भी कार्य प्रबंधक आप उपयोग करना चाहते हैं (अजवाइन भी एक विकल्प है), निम्न की तरह एक कमांड चलाने के लिए जो कुछ गणना के अनुसार रैंक को अपडेट करेगा और पुराने रिकॉर्ड को शुद्ध करेगा। निम्नलिखित कोड एक चित्रण है यह कैसे किया जा सकता है। वास्तविक कोड को आम तौर पर निष्क्रिय होने के लिए डिज़ाइन किया जाना चाहिए (निम्न कोड इसलिए नहीं है क्योंकि रैंक गणना यादृच्छिक है) ताकि यदि सर्वर को अपडेट के बीच में रिबूट किया जाता है, तो कमांड को फिर से चलाया जा सकता है। यह रहा कोड:

import random
import datetime
from optparse import make_option
from django.utils.timezone import utc

from django.core.management.base import BaseCommand
from school.models import Rank, Student

def utcnow():
    return datetime.datetime.utcnow().replace(tzinfo=utc)

class Command(BaseCommand):
    help = "Compute ranks and cull the old ones"
    option_list = BaseCommand.option_list + (
        make_option('--fake-now',
                    default=None,
                    help='Fake the now value to X days ago.'),
    )

    def handle(self, *args, **options):
        now = utcnow()
        fake_now = options["fake_now"]
        if fake_now is not None:
            now -= datetime.timedelta(days=int(fake_now))
            print "Setting now to: ", now

        for student in Student.objects.all():
            # This simulates a rank computation for the purpose of
            # illustration.
            rank_value = random.randint(1, 1000)
            try:
                rank = Rank.objects.get(student=student, date=now)
            except Rank.DoesNotExist:
                rank = Rank(
                    student=student, date=now)
            rank.value = rank_value
            rank.save()

        # Delete all ranks older than 180 days.
        Rank.objects.filter(
            date__lt=now - datetime.timedelta(days=180)).delete()

अचार क्यों नहीं?

कई कारण:

  1. यह एक समयपूर्व अनुकूलन है, और कुल मिलाकर शायद अनुकूलन बिल्कुल नहीं है। कुछ ऑपरेशन तेज हो सकते हैं, लेकिन अन्य ऑपरेशन धीमा होगा। यदि रैंकों को Student . पर किसी फ़ील्ड में चुना जाता है फिर, किसी विशिष्ट छात्र को स्मृति में लोड करने का अर्थ है उस छात्र के साथ सभी रैंक जानकारी को स्मृति में लोड करना। इसे .values() . का उपयोग करके कम किया जा सकता है या .values_list() लेकिन फिर आपको Student नहीं मिल रहा है डेटाबेस से उदाहरण। क्यों है Student उदाहरण पहली जगह में और न केवल कच्चे डेटाबेस तक पहुंचें?

  2. अगर मैं Rank में फ़ील्ड बदलता हूं , जब मैं अपने एप्लिकेशन का नया संस्करण परिनियोजित करता हूं, तो Django की माइग्रेशन सुविधाएं आसानी से आवश्यक परिवर्तन करने की अनुमति देती हैं। यदि किसी क्षेत्र में रैंक की जानकारी चुनी जाती है, तो मुझे कस्टम कोड लिखकर किसी भी संरचना परिवर्तन का प्रबंधन करना होगा।

  3. डेटाबेस सॉफ्टवेयर अचार में मूल्यों तक नहीं पहुंच सकता है और इसलिए आपको उन तक पहुंचने के लिए कस्टम कोड लिखना होगा। उपरोक्त मॉडल के साथ, यदि आप छात्रों को आज रैंक के आधार पर सूचीबद्ध करना चाहते हैं (और आज के लिए रैंक की गणना पहले ही की जा चुकी है), तो आप यह कर सकते हैं:

    for r in Rank.objects.filter(date=utcnow()).order_by("value")\
        .prefetch_related():
        print r.student.name
    

    यदि आप अचार का उपयोग करते हैं, तो आपको सभी Students को स्कैन करना होगा और जिस दिन आप चाहते हैं, उसके लिए रैंक निकालने के लिए रैंक को अनपिक करें, और फिर रैंक के आधार पर छात्रों को ऑर्डर करने के लिए पायथन डेटा संरचना का उपयोग करें। एक बार यह हो जाने के बाद, आपको नामों को क्रम में लाने के लिए इस संरचना पर पुनरावृति करनी होगी।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. क्या Npgsql पर FETCH को सीधे पैरामीटर के रूप में एक रेफकर्सर पास करना संभव है?

  2. रूबी ऑन रेल्स 5.2 में ActiveRecord माइग्रेशन में तालिका बनाते समय उपयोग करने के लिए अनुक्रम को कैसे परिभाषित करें?

  3. बैच के साथ बैचअपडेट अपवाद को संभालना

  4. पोस्टग्रेज में सशर्त INSERT INTO स्टेटमेंट

  5. सम्मिलित क्वेरी में इनपुट के रूप में चुनिंदा क्वेरी के आउटपुट का उपयोग कैसे करें?