简体   繁体   中英

Why does my python script to populate a Django table with dummy data from another table result in error?

So the title states my objective. Here's the code I wrote to achieve it:

#for each cycle in instructional cycles:
for cycle in Instructional_Cycle.objects.all():

    #for each standard in the currently selected cycle:
    for standard in cycle.standards.all():

        #generate random percentage of correct grade-level students to pass that standard, say between 20 and 90%
        percent_pass = randint(20,90)

        #calculate number of total students for that grade-level that percentage represents (percentage times total number of students in that grade)
        total_students_passing = (percent_pass/100) * Student.objects.filter(grade_level = standard.grade_level).count()

        already_selected = []

        #while length of list of already selected students < total needed
        while len(already_selected) < total_students_passing:

            #select a random student out of that grade
            count = Student.objects.filter(grade_level=standard.grade_level).count()
            random_student = Student.objects.all()[randint(0, count - 1)] #single random object

            #if that student isn't in list of already selected students
            if not random_student.id in already_selected:

                #create a passing progress report with the end date of that instructional cycle
                Progress_Report.objects.create(date=cycle.date_finished, student=random_student, standard_mastered=standard, mastery_status=True)

                #add that student to list of already selected students
                already_selected.append(random_student.id)

This ends with the following error:

django.db.utils.IntegrityError: UNIQUE constraint failed: 
student_progress_progress_report.standard_mastered_id

The progress_report table that I'm trying to fill is empty. I can add records to it using the admin interface. So I'm not sure where to look to fix my issue, because I'm not really sure what the problem is. Thanks for looking and any tips that you can provide. -- GH

Here are the models:

from django.db import models
from django.urls import reverse

gradeLevels = ((6,6), (7,7),(8,8),(9,9), (10,10), (11,11), (12,12))
subjects = (('Literacy','Literacy'), ('Math','Math'),
    ('Science','Science'), ('Social Studies','Social Studies'))


class Student(models.Model):

    student_id = models.CharField(max_length=8, unique=True)
    last_name = models.CharField(max_length=100)
    first_name = models.CharField(max_length=100)
    grade_level = models.IntegerField(choices=gradeLevels)
    active_status = models.BooleanField(default=True)

    class Meta:
        ordering = ['grade_level', 'last_name']

    def __str__(self):
        #Return a string representation of the model.
        return self.student_id + ' ' + self.last_name + ', ' + self.first_name

    def student_name(self):
        return self.last_name + ', ' + self.first_name

    def get_absolute_url(self):
        return reverse('student_progress:student_detail', args=[str(self.id)])

class Standard(models.Model):

    subject = models.CharField(max_length=14, choices=subjects)
    grade_level = models.IntegerField(choices=gradeLevels)
    descriptor = models.CharField(max_length=15)
    description = models.TextField()
    essential_status = models.BooleanField(default=False)


    class Meta:
        ordering = ["subject", "grade_level", "descriptor"]

    def __str__(self):
        return self.descriptor + ': ' + self.description[:100]

    def get_absolute_url(self):
        return reverse('student_progress:standard_detail', args=[str(self.id)])

class Milestone (models.Model):

    step_number = models.IntegerField()
    statement = models.CharField(max_length=250, default="I can ...")
    standard = models.ForeignKey(Standard, on_delete=models.CASCADE,         
        related_name='milestones', null=True, blank=True)

    def __str__(self):
        return str(self.step_number) + ': ' + self.statement[:50]

class Progress_Report(models.Model):

    date = models.DateField(null=True)
    student = models.OneToOneField(Student, on_delete=models.CASCADE)
    standard_mastered = models.OneToOneField(Standard, 
        on_delete=models.CASCADE)
    mastery_status = models.BooleanField(default=True)

    class Meta:
        ordering = ["date", "student"]

    def __str__(self):
        return self.date

class Instructional_Cycle(models.Model):
    date_started = models.DateField(blank=False)
    date_finished = models.DateField(blank=False)
    standards = models.ManyToManyField(Standard, related_name="standards")

    class Meta:
        ordering = ['date_started']

    def __str__(self):
        return str(self.date_started) + ' to ' + str(self.date_finished)

    def get_absolute_url(self):
        return reverse('student_progress:cycle_detail', args=[str(self.id)])

you've told the database you want to maintain a unique constraint! the data you're trying to insert would violate that constraint and therefore the transaction is failing.

Django provides various helpers for this. For example Progress_Report.objects.update_or_create(…) might help. For more info, see:

https://docs.djangoproject.com/en/2.1/ref/models/querysets/#update-or-create

The exact invocation would depend on the constraints you're wanting to enforce.

I stumbled on the answer accidentally: I changed the field types of Progress_Report.student and Progress_Report.standard_mastered from OnetoOneField to ForeignKey. Now the python code runs perfectly and populates the database exactly as intended without error.

I have no idea why this solved the problem. I wish I understood better what the problem is, but I'm thankful it's fixed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM