2 votes

Comment créer ou mettre à jour en masse dans Django

Je dois traiter un fichier CSV de rapport d'articles toutes les heures. Le fichier CSV contient plus de 150 000 enregistrements pour un compte et il y a plusieurs comptes dans mon système. Je travaillais auparavant sur rails et il y avait une gemme active record pour gérer ce cas d'utilisation très efficacement. Je cherche une alternative à cette gemme dans Django ou une méthode intégrée qui serait utile pour importer de telles données en masse.

Jusqu'à présent, j'ai essayé ce code.

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'
            ]
        )

Cette exception est soulevée parce que lorsqu'un nouveau produit est créé, aucune clé primaire ne lui est attribuée.

ValueError : Tous les objets bulk_update() doivent avoir une clé primaire définie.

0voto

fahad Points 125

Vous ne sauvegardez pas le produit dans la base de données avant d'appliquer bulk_update. J'ai vérifié votre code à cette fin, vous pouvez utiliser bulk_insert avec un paramètre supplémentaire

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

o

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)

A la fin, vous pouvez faire une mise à jour en masse comme

Model.objects.bulk_update(items_to_be_inserted, columns)

Cela résoudra votre problème.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X