Форум сайта python.su
Ув. сообщество, я только начинаю знакомство с django и python в целом.
Как лучше всего обрабатывать csv файлы большого размера?
На данном этапе работает следующий код:
class Distr(models.Model): name = models.CharField(max_length=20, verbose_name="Название") mail = models.EmailField() file = models.FileField(upload_to="csv", blank=True, verbose_name="Файл CSV") def save(self): super(Distr, self).save() csv_file = self.file.path dataReader = csv.reader(open(csv_file), delimiter=',', lineterminator='\n') for row in dataReader: tovar = Item() if row[0] != 'Бла-бла-бла': filter = Item.objects.filter(distr = self, artikul = row[0]) if filter: exist = filter.get() exist.price = row[2] exist.count = row[3] exist.save() else: tovar.artikul = row[0] tovar.name = row[1] tovar.distr = self tovar.price = row[2] tovar.count = row[3] tovar.save()
Отредактировано hulygun (Окт. 31, 2012 13:40:55)
Офлайн
Вот это
dataReader = csv.reader(open(csv_file), delimiter=',', lineterminator='\n')
with open(csv_file, 'rb') as f: dataReader = csv.reader(f, delimiter=',', lineterminator='\n')
Офлайн
Если ключевая строка
if row[0] != 'Бла-бла-бла':
Офлайн
За генератор отдельное спасибо. Но вот только всё равно за раз 8к запросов к базе не сильно ли много?
Офлайн
Опять же, зависит от ресурсов и мощности железа.
Но, в любом случае, вам лучше явно управлять транзакциями. Сейчас, судя по коду, у вас каждое изменение - отдельная транзакция - это создает ненужную нагрузку на БД в данном случае.
Для вашей конфигурации сервера опытным путем установите размер пакета записей, сохраняемых в одной транзакции.
Если у вас хостинг, начните с 100 штук и двигайтесь в сторону увеличения, пока не получите наивысшую производительность.
Если VDS, начните с 500 штук.
Если свой сервер,- с 1000.
Офлайн
Смысл в следующем:
Есть сущность Дистрибьютер(Distr), которая заполняется вручную админом, у каждого дистрибьютора есть csv с товарами. Тоесть админ заполняет поля этой сущности, загружает csv и создаются автоматом товары. Как делать
Lexanderя понятия не имею (скилл слишком мал). Но и на том спасибо. Завтра буду пробовать копать в этом направлении. Правда я даже понятия не имею, как поставить вопрос гуглу((( Пока проект на локале, но думаю в будущем будет vds.
установите размер пакета записей, сохраняемых в одной транзакции
Офлайн
hulygunЧто-то вроде “django manual commit”
Правда я даже понятия не имею, как поставить вопрос гуглу
from django.db import transaction BULK_SAVE_COUNT = 500 class Distr(models.Model): ... @transaction.commit_manually def save(self): ... added_items = 0 for row in dataReader: ... something.save() added_items += 1 if not added_items % BULK_SAVE_COUNT: transaction.commit() transaction.commit()
Отредактировано reclosedev (Ноя. 1, 2012 06:47:10)
Офлайн
О…. благодарю великодушно… ушёл копать
Офлайн
Я в джанго тоже не очень опытный, но по опыту PHP и Perl могу сказать, что разницу в производительности вы не очень почувствуете при размере файла в 8к строк, если, конечно, это не будут делать одновременно постоянно десяток человек. Загрузить такой файл несколько раз в сутки нормально с точки зрения нагрузки на железо и БД. Только с оговоркой, что добрые соседи по железу на VDS в этот момент не уматывают ресурсы общего железного сервера в хлам.
Офлайн
если у вас действительно большие файлы, то мне кажется лучше вынести логику его обработки куда-то вне основного потока, повесьте celery task на post_save, а в самом task уже делайте импорт файла, иначе у вас могут возникнуть проблемы, например, с request timeout
import this
Офлайн