【问题标题】:How to bulk create or update in Django如何在 Django 中批量创建或更新
【发布时间】:2021-07-09 09:08:00
【问题描述】:

我必须每 1 小时处理一次项目报告 CSV 文件。 CSV 包含 1 个帐户的 150k+ 条记录,并且我的系统中有多个帐户。我以前在 Rails 上工作,并且有活动记录 gem 可以非常有效地处理这个用例。我正在寻找 Django 中此 gem 的替代方法或任何有助于批量导入此类大数据的内置方法。

到目前为止,我已经尝试过这段代码。

class ItemReportService:

    def call(self, file_url):
        with open(file_url, 'r') as file:
            reader = csv.DictReader(file)
            products = []
            for row in reader:
                product = self.process_product(row)
                products.append(product)

            self.update_products(products)

    def process_product(self, row):
        print(f'Processing sku: {row["SKU"]}')
        product = Product.objects.filter(
            sku=row['SKU']).first() or Product(sku=row['SKU'])
        product.listing_title = row['Product Name']
        product.listed_price = row['Price']
        product.buy_box_price = row['Buy Box Item Price'] + \
            row['Buy Box Shipping Price']
        product.status = row['Lifecycle Status']
        return product

    def update_products(self, products):
        Product.objects.bulk_update(
            products,
            [
                'listing_title',
                'listed_price',
                'buy_box_price',
                'Lifecycle Status'
            ]
        )

它引发了这个异常,因为当有一个新产品时它没有分配主键

ValueError: 所有 bulk_update() 对象都必须有一个主键集。

【问题讨论】:

  • 您必须先创建和获取/过滤对象。然后对对象实例进行批量更新。
  • 谢谢 Siva 我已经试过了。我只想根据 SKU 查找产品,所以它会引发错误,不要将其余字段留空。
  • 谢谢詹姆斯知道了。

标签: python-3.x django


【解决方案1】:

在应用 bulk_update 之前,您没有将产品保存在数据库中。 我已经为此检查了您的代码,您可以使用带有附加参数的 bulk_insert

Model.objects.bulk_create(self.data, ignore_conflicts=True)

columns = ['column1', 'column2']
obj = Model.objects.filter(column1="sku").first()
if not obj:
   obj = Model.objects.create(column1="sku")
obj.column1 = row["column1"] or obj.column1
obj.column2 = row["column2"] or obj.column2
items_to_be_inserted.append(obj)

最后,你可以像这样进行批量更新

Model.objects.bulk_update(items_to_be_inserted, columns)

这将解决您的问题。

【讨论】:

  • 请注意,这不适用于 PostgreSQL
  • 如果数据库中已经存在对象,则忽略它们
  • 更新了答案。
猜你喜欢
  • 2015-01-18
  • 2020-07-19
  • 2014-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-16
  • 2012-12-16
  • 1970-01-01
相关资源
最近更新 更多