这是我的项目设置,使用标准的Django startproject命令和一个应用程序:
Python 3.5.1
Django 1.9.7
PostgreSQL 9.5.3
Ubuntu 16.04
应用程序的models.py定义了2个模型:
from django.db import models
class A(models.Model):
n = models.PositiveIntegerField(primary_key=True)
class B(models.Model):
a = models.ForeignKey(A, blank=True, null=True)
m = models.CharField(max_length=20, db_index=True)
class Meta:
unique_together = ('a', 'm')
def __str__(self):
return '%s' % self.m
这是我的名为execute.py的管理命令,用于创建B的实例:
from multiprocessing import Pool
from django import db
from django.core.management.base import BaseCommand
from .models import B
M = 'abcdef'
def create():
obj, created = B.objects.get_or_create(m=M, defaults={'a': None})
if created:
print('obj=%s' % obj)
class Command(BaseCommand):
def handle(self, *args, **kwargs):
B.objects.filter(m=M).delete()
db.connections.close_all()
n = 4
pool = Pool(processes=n)
results = []
for _ in range(n):
result = pool.apply_async(create)
results.append(result)
pool.close()
for result in results:
result.get()
pool.join()
运行 python manage.py execute 会导致创建4个obj而不是1。但情况并非总是这样。有时,只创建了3个甚至只有1个对象:
obj=abcdef
obj=abcdef
obj=abcdef
obj=abcdef
我是否遗漏了一些在这里强制执行的独特性?
答案 0 :(得分:0)
documentation for get_or_create()
:
此方法是原子的,假设正确使用,正确的数据库配置和底层数据库的正确行为。 但是,如果未在数据库级别强制执行唯一性 [...],则此方法容易出现竞争条件,这可能会导致多行具有相同的参数同时插入。
function clicker(){
alert ("Step 1.9: Clearly it is entering func");
$("#button").click(function(){
alert("Step 2 ALERT"); //SKIPS THIS PART
})
}
$(document).ready(function(){
alert("hello, step 1");
if (1==1) {
clicker();
alert("Step 3:Done with 'if' ");
}
alert("step 4 DONE with whole code");
})
模型的m
字段没有B
约束,这导致竞争条件。将字段定义更改为:
unique=True
你应该没事。