Reputation: 109
I have a get_or_create() in my django app that's creating duplicate rows and assigning them the same id.
stock_search, created = SearchRequest.objects.get_or_create(quote=quote, salesperson=user)
count() doesn't count these rows more than once but any queries I run on the data returns the duplicated rows.
Any ideas what could be causing this to happen?
Model Definition
class SearchRequest(models.Model):
salesperson = models.ForeignKey(User, blank=True, null=True, related_name='sales')
purchaser = models.ManyToManyField(User, blank=True, null=True, related_name='purchaser')
datesent = models.DateTimeField(auto_now_add=False, verbose_name=("Date Sent"), blank=True, null=True)
notes = models.TextField(default='', blank=True, null=True)
full_search = models.BooleanField(verbose_name=("Full Search"), blank=True, default=False)
quote = models.ForeignKey('Quote.Quote', blank=True, null=True)
lead_time = models.ForeignKey('Logistics.LeadTime', blank=True, null=True)
call_list = models.BooleanField(verbose_name=("Call List"), blank=True, default=False)
email_list = models.BooleanField(verbose_name=("Email List"), blank=True, default=False)
accepted = models.ForeignKey(User, blank=True, null=True, related_name='search_accepted')
dateaccepted = models.DateTimeField(auto_now_add=False, verbose_name=("Date Accepted"), blank=True, null=True)
Cheers
Upvotes: 0
Views: 4214
Reputation: 53774
As mentioned in the docs, you need an unique index for get_or_create to work
This method is atomic assuming correct usage, correct database configuration, and correct behavior of the underlying database. However, if uniqueness is not enforced at the database level for the kwargs used in a get_or_create call (see unique or unique_together), this method is prone to a race-condition which can result in multiple rows with the same parameters being inserted simultaneously.
So you class needs
class SearchRequest(models.Model):
class Meta:
unique_together('quote','salesperson')
which should be placed after the field definitions.
Upvotes: 4