I have two models, namely Project and Hourly. Whenever a new project is created, I want to also generate 8760 new Hourly instances.
There are two methods, one is very costly since 8760 times a new row is written to the database, i.e.:
for i in range(0, 24):
clock_time=i*3600
hourly = Hourly.objects.create(project=project, clock_time=clock_time)
hourly.save()
The other method is by using the Django bulk_create(hourlys) method, which works fine whenever I use the default Hourly() constructor. However I want to use my custom Hourly.objects.create() function. This however gives an UNIQUE constraint error for hourly.id, i.e.:
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, this is the wrong way to bulk_create.
hourlys = []
for i in range(0, 24):
hourlys.append(Hourly.objects.create(project=project,
clock_time=clock_time))
Hourly.objects.bulk_create(hourlys)
The proper way is you pass the attributes to the Hourly object creating a list of that. A compressed version would look like this here below.
hourlys = [Hourly(project=project, clock_time=i*3600) for i in range(24)]
hourlys_objects = Hourly.objects.bulk_create(hourlys)
See link here for more
As explained above when you call Hourly.objects.create the object is created (with a hit to the database also defeating the purpose of using bulk_create optimization).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With