I have a table in my postgresql db holding a state of an hour record. For each month, project and user I need exactly one state. I'm using the get_or_create method to either create a "state" or to retrieve it if it already exists.
HourRecordState.objects.get_or_create(user=request.user, project=project, month=month, year=year, defaults={'state': 0, 'modified_by': request.user})
After running this for about two years without problems I stumbled over the problem that I have one HourRecordState twice in my database. Now each time the get_or_create method is called it throws the following error:
MultipleObjectsReturned: get() returned more than one HourRecordState -- it returned 2
I'm wondering how it could happen that I have two identical records in my DB. Interestingly they have been created at the same time (seconds, not checked the milliseconds).
I checked my code and I have in the whole project only one get_or_create method to create this object. No other create methods in the code.
Would be great to get a hint..
Update:
The objects have been created at almost the same time: First object: 2011-10-04 11:04:35.491114+02 Second object: 2011-10-04 11:04:35.540002+02
And the code:
try:
project_id_param = int(project_id_param)
project = get_object_or_404(Project.objects, pk=project_id_param)
#check activity status of project
try:
is_active_param = project.projectclassification.is_active
except:
is_active_param = 0
if is_active_param == True:
is_active_param = 1
else:
is_active_param = 0
#show the jqgrid table and the hour record state form
sub_show_hr_flag = True
if project is not None:
hour_record_state, created = HourRecordState.objects.get_or_create(user=request.user, project=project, month=month, year=year, defaults={'state': 0, 'modified_by': request.user})
state = hour_record_state.state
manage_hour_record_state_form = ManageHourRecordsStateForm(instance=hour_record_state)
if not project_id_param is False:
work_place_query= ProjectWorkPlace.objects.filter(project=project_id_param, is_active=True)
else:
work_place_query = ProjectWorkPlace.objects.none()
work_place_dropdown = JQGridDropdownSerializer().get_dropdown_value_list_workplace(work_place_query)
except Exception, e:
project_id_param = False
project = None
request.user.message_set.create(message='Chosen project could not be found.')
return HttpResponseRedirect(reverse('my_projects'))
Well this is not an exact answer to your question, but I think you should change your database scheme and switch to using UNIQUE
constraints that help you to maintain data integrity, as the uniqueness will be enforced on database level.
If you state that for every month, user and project you need exactly one state, your model should look something like this (using the unique_together
constraint):
class HourRecordState(models.Model):
user = models.ForeignKey(User)
project = models.ForeignKey(Project)
month = models.IntegerField()
year = models.IntegerField()
# other fields...
class Meta:
unique_together = ((user, project, month, year),)
Because get_or_create
is handled by django as a get
and create
multiple processes seem to be able under certain condition to create the same object twice, but if you use unique_together
an exception will be thrown if the attempt is made....
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