I don't know if this will make you happy but when I researched this some months ago I found no good solution.
During my search I came upon the following pages that sort of relate to this...
- http://github.com/dcramer/django-idmapper
- http://appengine-cookbook.appspot.com/recipe/high-concurrency-counters-without-sharding/
- http://pastie.org/615863
- http://stackoverflow.com/questions/3522827/handling-race-condition-in-model-save-django
I ended up using something similar to the stackoverflow solution.
I needed to generate a new number per "produced_at" date in a model called Entity and ended up with the following custom .save method.
This is a pretty rough copy-paste so things might not work out of the box but the principle is there.
class Entity(models.Model):
...
created_at = models.DateTimeField(auto_now_add=True)
produced_at = models.DateField(default=datetime.now)
number = models.PositiveIntegerField(default=1)
class Meta:
unique_together=(('produced_at', 'number'))
def save(self, *args, **kwargs):
if self.id: #do a normal save
super(Entity, self).save(*args, **kwargs)
return
while not self.id:
try:
max = Entity.objects.filter(produced_at=self.produced_at).aggregate(Max('number'))
if max['number__max']:
self.number = max['number__max']+1
else:
self.number=1
#Trying to save with number = self.number
super(Entity, self).save(*args, **kwargs)
except IntegrityError:
# conflicting number, chill out and try again
sleep(uniform(0.1, 0.6)) #chill out, then try again
# try again then
You received this message because you are subscribed to the Google Groups "Django users" group.
To post to this group, send email to django-users@googlegroups.com.
To unsubscribe from this group, send email to django-users+unsubscribe@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/django-users?hl=en.
No comments:
Post a Comment