Update_or_create不会尊重唯一键

时间:2021-04-21 04:25:29

I'm using the following model in Django:

我在Django中使用以下模型:

class sfs_upcs(models.Model):
  upc = models.CharField(max_length=14, unique=True)
  product_title = models.CharField(max_length=150,default="Not Available")
  is_buyable = models.NullBooleanField()
  price = models.DecimalField(max_digits=8, decimal_places=2,default="0.00")
  image_url = models.URLField(default=None)
  breadcrumb = models.TextField(default=None)
  product_url = models.URLField(default=None)
  timestamp = models.DateTimeField(auto_now=True)

And then I'm using the following code on my views.py:

然后我在我的视图中使用以下代码。

def insert_record(upc_dict):
  upc = upc_dict['upc']
  product_title = upc_dict['product_title']
  is_buyable = upc_dict['is_buyable']
  price = upc_dict['price']
  image_url = upc_dict['image_url']
  breadcrumb = upc_dict['breadcrumb']
  product_url = upc_dict['product_url']
  obj, created = sfs_upcs.objects.update_or_create(
    defaults={'product_title':product_title,'is_buyable':is_buyable,
    'price':price,'image_url':image_url,'breadcrumb':breadcrumb,'product_url':product_url
    },
    upc = upc,
    product_title = product_title,
    is_buyable = is_buyable,
    price = price,
    image_url = image_url,
    breadcrumb = breadcrumb,
    product_url = product_url)

  print obj,created

I'm using the update_or_create method present in the documentation https://docs.djangoproject.com/en/1.8/ref/models/querysets/#update-or-create and says that by passing into the 'defaults' dictionary the values that you want to UPDATE in case the object exists should make the trick... but I keep getting an "IntegrityError at ... column upc is not unique"...

我正在使用文档中出现的update_or_create方法https://docs.djangoproject.com/en/1.8/ref/models/querysets/# UPDATE -or-create,并说通过将您想要更新的值传递到“默认”字典中,以防对象存在,这将会使问题变得复杂…但我总是在……upc列不是唯一的。

Any ideas?

什么好主意吗?

1 个解决方案

#1


31  

There are two parts to update_or_create(): the filter values to select an object, and the update values that are actually updated. The keywords filter the object to update, the defaults are the values that are updated. If there is no match for the filters, a new object is created.

update_or_create()包含两个部分:选择对象的筛选值和实际更新的更新值。关键字筛选要更新的对象,默认值是要更新的值。如果没有匹配的过滤器,将创建一个新的对象。

Right now you're filtering on all of these values, since they're all provided as keyword arguments:

现在您正在过滤所有这些值,因为它们都是作为关键字参数提供的:

upc = upc,
product_title = product_title,
is_buyable = is_buyable,
price = price,
image_url = image_url,
breadcrumb = breadcrumb,
product_url = product_url

The IntegrityError means that, even though that specific value for upc exists, an object matching all of these filters does not exist. Django then tries to create the object instead, but the upc is not unique, so this causes an IntegrityError.

完整性错误意味着,即使upc的特定值存在,匹配所有这些过滤器的对象也不存在。然后Django尝试创建对象,但是upc不是惟一的,因此这会导致一个完整性错误。

If you filter on just the upc, that field will never cause an IntegrityError to be raised: either an existing object is found and updated, or a new object is created, but the value for upc is unique.

如果只对upc进行筛选,则该字段永远不会引发完整性错误:要么找到并更新现有对象,要么创建新对象,但upc的值是惟一的。

So to fix this, simply do:

要解决这个问题,只需:

obj, created = sfs_upcs.objects.update_or_create(
    # filter on the unique value of `upc`
    upc=upc,
    # update these fields, or create a new object with these values
    defaults={
        'product_title': product_title, 'is_buyable': is_buyable,  'price': price, 
        'image_url': image_url, 'breadcrumb': breadcrumb, 'product_url': product_url,
    }
)

#1


31  

There are two parts to update_or_create(): the filter values to select an object, and the update values that are actually updated. The keywords filter the object to update, the defaults are the values that are updated. If there is no match for the filters, a new object is created.

update_or_create()包含两个部分:选择对象的筛选值和实际更新的更新值。关键字筛选要更新的对象,默认值是要更新的值。如果没有匹配的过滤器,将创建一个新的对象。

Right now you're filtering on all of these values, since they're all provided as keyword arguments:

现在您正在过滤所有这些值,因为它们都是作为关键字参数提供的:

upc = upc,
product_title = product_title,
is_buyable = is_buyable,
price = price,
image_url = image_url,
breadcrumb = breadcrumb,
product_url = product_url

The IntegrityError means that, even though that specific value for upc exists, an object matching all of these filters does not exist. Django then tries to create the object instead, but the upc is not unique, so this causes an IntegrityError.

完整性错误意味着,即使upc的特定值存在,匹配所有这些过滤器的对象也不存在。然后Django尝试创建对象,但是upc不是惟一的,因此这会导致一个完整性错误。

If you filter on just the upc, that field will never cause an IntegrityError to be raised: either an existing object is found and updated, or a new object is created, but the value for upc is unique.

如果只对upc进行筛选,则该字段永远不会引发完整性错误:要么找到并更新现有对象,要么创建新对象,但upc的值是惟一的。

So to fix this, simply do:

要解决这个问题,只需:

obj, created = sfs_upcs.objects.update_or_create(
    # filter on the unique value of `upc`
    upc=upc,
    # update these fields, or create a new object with these values
    defaults={
        'product_title': product_title, 'is_buyable': is_buyable,  'price': price, 
        'image_url': image_url, 'breadcrumb': breadcrumb, 'product_url': product_url,
    }
)