我有以下Django模型:
class Property(models.Model):
name = models.TextField(unique=True, db_index=True)
class AirtableProduct(models.Model):
internal_id = models.IntegerField(unique=True, db_index=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class AirtableProductPropertyValue(models.Model):
airtable_product = models.ForeignKey(AirtableProduct, on_delete=models.CASCADE, related_name='properties')
property = models.ForeignKey(Property, on_delete=models.CASCADE)
value = models.TextField()
class Meta:
unique_together = (('airtable_product', 'property'),)
index_together = [
'airtable_product', 'property'
]
它们表示一个由internal_id标识的对象(AirtableProduct),以及我用Property和AirtableProductPropertyValue表表示的可变数量的属性。
在创建/更新产品及其属性时,问题出现在以下代码中:
// products is an array of dictionary with the properties as key/value
def insert_all_airtable_products(products):
logger.info('Inserting Airtable products into the database')
for product in products:
internal_id = product.pop('Internal ID')
ap, created = AirtableProduct.objects.get_or_create(internal_id=internal_id)
for field in product:
property, created = Property.objects.get_or_create(
name=strip_spaces(field)
)
ap_pv, created = AirtableProductPropertyValue.objects.get_or_create(airtable_product=ap, property=property)
ap_pv.value = strip_spaces(product[field])
ap_pv.save()
我有10,000个产品,每个产品都有20多个属性,因为我必须遍历每个产品并更新/创建旧/新属性,这项操作的成本很高,需要花费大量时间数据库。
怎样才能让它变得更好?
答案 0 :(得分:0)
您可以从数据库中获取所有AirtableProducts及其AirtableProductPropertyValue和Property,将它们存储在字典中并使用它们代替get_or_create。
您也可以使用bulk_create而不是每次都调用object.save()。以下代码说明了它:
airtable_product_dict = {}
queryset = AirtableProduct.objects.prefetch_related(
'properties', 'properties__property')
for airtable_product in queryset:
airtable_product_dict[airtable_product.internal_id] = airtable_product
new_aritable_products = []
for product in products:
internal_id = product.pop('Internal ID')
if internal_id not in aritable_product_dict:
new_airtable_products.append(AirtableProduct(internal_id))
# Follow similar logic ahead
AirtableProduct.objects.bulk_create(new_airtable_products)
注意: