我有两个模型,分别是Project和Hourly。每当创建新项目时,我还想生成8760个新的Hourly实例。

有两种方法,一种是非常昂贵的,因为8760次将新行写入数据库,即:

for i in range(0, 24):
    clock_time=i*3600
    hourly = Hourly.objects.create(project=project, clock_time=clock_time)
    hourly.save()


另一种方法是使用Django bulk_create(hourlys)方法,只要我使用默认的Hourly()构造函数,该方法就可以正常工作。但是我想使用自定义的Hourly.objects.create()函数。但是,这给出了hourly.id的UNIQUE约束错误,即:

class HourlyManager(models.Manager):
    """"""
    def create(self, project, clock_time):
        hourly = super().create(project=project, clock_time=clock_time)
        hourly.local_civil_time = services.calc_local_civil_time(clock_time,
                                                                 project.TMZ,
                                                                 project.lon)
        hourly.save()
        return hourly


class ProjectManager(models.Manager):
    """"""
    def create(self, owner, project_name, TMZ, lat, lon):
        project = super().create(owner=owner, project_name=project_name, TMZ=TMZ, lat=lat, lon=lon)
        project.save()

        hourlys = []
        for i in range(0, 24):
            hourlys.append(Hourly.objects.create(project=project, clock_time=clock_time))
        Hourly.objects.bulk_create(hourlys)

        return project


class Project(models.Model):
    objects = ProjectManager()

    owner           = models.ForeignKey('auth.User', related_name='projects', on_delete=models.CASCADE)
    project_name    = models.CharField(max_length=200)
    TMZ             = models.FloatField(default=0)
    lat             = models.FloatField(default=0)  # Radians
    lon             = models.FloatField(default=0)  # Radians


class Hourly(models.Model):
    objects = HourlyManager()

    project             = models.ForeignKey(Project, related_name='hourlys', on_delete=models.CASCADE)
    clock_time          = models.FloatField(default=0)
    local_civil_time    = models.FloatField(default=0)

最佳答案

@arne,这是批量创建的错误方法。

    hourlys = []
    for i in range(0, 24):
        hourlys.append(Hourly.objects.create(project=project,
     clock_time=clock_time))
     Hourly.objects.bulk_create(hourlys)


正确的方法是将属性传递给Hourly对象,以创建该对象的列表。压缩版本如下所示。

hourlys = [Hourly(project=project, clock_time=i*3600) for i in range(24)]
hourlys_objects = Hourly.objects.bulk_create(hourlys)


有关更多信息,请参见link here

如上文所述,当您调用Hourly.objects.create时,将创建对象(对数据库的点击也使使用bulk_create优化的目的无效)。

关于django - 使用Django bulk_create会给UNIQUE约束失败:solgeo_hourly.id,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48932669/

10-09 06:08