get_or_create的问题——结果在DB中创建了两个对象



我有一个表在我的postgresql数据库中保存一个小时记录的状态。对于每个月,项目和用户I只需要一个状态。我使用get_or_create方法来创建一个"状态",或者在它已经存在的情况下检索它。

HourRecordState.objects.get_or_create(user=request.user, project=project, month=month, year=year, defaults={'state': 0, 'modified_by': request.user})

在运行了大约两年没有问题之后,我偶然发现了我在数据库中两次有一个HourRecordState的问题。现在每次调用get_or_create方法时,它都会抛出以下错误:

MultipleObjectsReturned: get()返回了多个HourRecordState——它返回2

我想知道它怎么可能发生,我有两个相同的记录在我的数据库。有趣的是,它们是同时创建的(秒,而不是毫秒)。

我检查了我的代码,我在整个项目中只有一个get_or_create方法来创建这个对象。代码中没有其他create方法。

如果能得到提示就太好了。

更新:

对象几乎是同时创建的:第一个对象:2011-10-04 11:04:35.491114+02第二对象:2011-10-04 11:04:35.540002+02

和代码:

    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'))

这不是你问题的确切答案,但我认为你应该改变你的数据库方案,并切换到使用UNIQUE约束来帮助你保持数据完整性,因为唯一性将在数据库级别强制执行。

如果你声明对于每个月,用户和项目你需要完全一个状态,你的模型应该看起来像这样(使用unique_together约束):

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),)

因为get_or_create被django处理为getcreate多个进程似乎能够在一定条件下创建相同的对象两次,但如果你使用unique_together一个异常将被抛出如果尝试....

最新更新