【发布时间】:2011-11-30 22:16:02
【问题描述】:
我的 postgresql 数据库中有一个表,其中包含一个小时记录的状态。对于每个月,项目和用户我都需要一个状态。 我正在使用 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 方法来创建这个对象。代码中没有其他创建方法。
如果能得到提示会很棒..
更新:
对象几乎同时被创建: 第一个对象: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'))
【问题讨论】:
-
1.对象的年龄(同时代码是否发生了变化)? 2. 你知道复制那个对象是不可能吗? 3.删除有问题吗? 4. 为什么没有唯一索引来防止这种情况发生?
-
1. 对象只有几个小时。同时代码没有改变。 2. 是的,我知道。 3. 不,我会删除它以解决问题,但我想了解这是如何发生的。 4. 好问题。将在数据库级别添加一个 unique_constraint。 5. 查看它已创建的时间戳。非常紧密地在一起.. 嗯!?
-
不看代码就没有人能回答这个问题。我的疯狂猜测是,第一次创建对象的代码被多个进程或线程同时执行。基本上你需要某种互斥,正如前面的评论所说,UNIQUE 约束可能是一个很好的解决方案。
-
我添加了代码块。我在我的数据库中添加了唯一约束。因此我不应该再遇到这个问题。然而奇怪的是代码块被执行了两次(不知何故跳过了 get_or_create 限制),而且在这么短的时间内。
-
猜猜
if project is not None将永远是True如果你之前使用get_object_or_404:)
标签: django postgresql