@vikholodov

Как ускорить импорт из csv в бд?

Имеем django, postgresql и 15 миллионов товаров в файле csv, все это импортируется в 1 поток.
Примерно так это делаю:
with open('new_products.csv', 'r', encoding='utf-8') as csvfile:
...
for row in rows:
    product = Product()
    product.price = row[0]
    product.shipping = row[1]
    product.save()

и так далее. Возможно есть какой-то способ ускорить этот процесс в несколько раз?
  • Вопрос задан
  • 397 просмотров
Пригласить эксперта
Ответы на вопрос 1
neatsoft
@neatsoft
Life is too short for bad software
1. Итерировать строки по несколько сотен штук, и создавать соответствующие им объекты единым вызовом к bulk_create:
import itertools

def grouper(iterable, n, fillvalue=None):
    args = [iter(iterable)] * n
    return itertools.zip_longest(*args, fillvalue=fillvalue)

...

limit = 250

for index, items in enumerate(grouper(rows, limit)):
    items = (i for i in items if i) # remove empty rows added by grouper

    products = []

    for item in items:
        product = Product(
            price=item[0],
            shipping=item[1],
        )
        products.append(product)

    Product.objects.bulk_create(products)

Все 15 миллионов объектов разом создавать не стоит - ничего хорошего из этого не выйдет.

2. Если необходимо создавать зависимые объекты, использовать транзакции:
from django.db import transaction

...

limit = 250

for index, items in enumerate(grouper(rows, limit)):
    with transaction.atomic():
        for item in (i for i in items if i):
            product = Product.objects.create(
                price=item[0],
                shipping=item[1],
            )
            # product can be used there to create another objects, e.g.:
            for color in item[2].split(','):
                ProductColor.objects.create(
                    product=product,
                    color=color,
                )

Транзакции, в данном случае, обеспечивают существенный прирост производительности.

3. Запустить несколько процессов, каждому из которых передать в параметрах с какой позиции он должен начать, и сколько строк обработать. Чтобы дочерним процессам не пришлось читать весь файл с самого начала, позицию лучше передавать не номером строки, а смещением.

4. Скомбинировать 3 и 1 или 3 и 2.

5. Модели в джанго - это просто таблицы в базе данных. Можно добавлять строки с помощью SQL запросов из отдельного скрипта на Python или Go.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы