L
L
Lorem Ipsum2014-07-16 20:34:56
Django
Lorem Ipsum, 2014-07-16 20:34:56

Django - How to properly use bulk_create?

Actually the question itself is in the title, and below is the code so that you yourself can run and say what I'm doing wrong.
The code below eats up 400MB of RAM and takes about 5 minutes to complete.
I have windows 8.1 x64, python 3.4.1, mysql connector from oracle.

# python 3.4.1
# models.py
from django.db import models


class Item(models.Model):
    name = models.TextField()
  

class ItemTitle(models.Model):
    category = models.ForeignKey(Item)
    name = models.TextField()
    translit = models.TextField()
    slugified = models.TextField()
    urlencoded_name = models.TextField()
    urlencoded_translit = models.TextField()
    hash = models.CharField(max_length=150, unique=True)

# Python 3.4.1
# examle.py
import os
import re
import random
import hashlib
from urllib.parse import quote_plus

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'for_test.settings')

from django.db import IntegrityError, transaction

# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
from app.models import Item, ItemTitle
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

def generator(count, length, file_object=None):
  words = '''
  В популярной игре «World of Warcraft» один из игроков («грифер» — англ. griefer — игрок, который играет лишь для того, чтобы портить игру другим) начинает убивать всех подряд, включая ребят из Саут-Парка. Этот грифер играл в игру каждый день за последние полтора года и каким-то образом смог обойти максимальное количество возможных уровней в игре. Он также смог обойти правила Blizzard’а, которые требуют обоюдного согласия перед поединком (дуэлью). Даже администраторы игры не могут его победить. Рэнди, отец Стэна также проявляет интерес к игре (после того, как сын называет его «ламером» и объясняет, что такое онлайн-игры), но грифер его быстро убивает.

  Картман собирает всех четвероклассников, чтобы спланировать нападение на грифера. Баттерс оказывается единственным из всех четвероклассников, не играющим в WoW (он играет в «Hello Kitty Island Adventure»), и Картман рекомендует ему установить WoW, пока все остальные его не убили. Сомневается в целесообразности атаки и Клайд, но Картман в конце концов уговаривает всех. Их план — войти в игру одновременно и напасть группой. В назначенный час Картман (в роли дварфа) начинает атаку, но грифер призывает гигантских скорпионов себе на помощь и легко отбивает атаку. Все парни сдаются и идут играть на улицу.

  Картман убеждает Стэна, Кайла и Кенни продолжать играть — «Вы можете бездарно провести эти дни на улице, бездумно гоняя мячик… а можете сесть за компьютер и совершить что-то важное». Следующие несколько недель ребята играют в игру двадцать один час в сутки, убивая кабанов в лесу (чтобы получить очки опыта) и прячась от грифера. Из-за ужасного образа жизни они быстро толстеют (Картман, который уже был толстым, становится просто чрезвычайно жирным), у них появляются прыщи; кроме того, ребята совершенствуют свой Интернет-жаргон, используя слова наподобие «Ьber» и «pwned» в обыденной речи. Персонажи ребят растут так быстро, что в Blizzard’е их замечают и понимают, что у них, как и у грифера, нет никакой личной жизни (англ. have no life).

  Понимая, что парням понадобится помощь в убийстве злодея, создатели игры решают дать им «Меч Тысячи Истин» — оружие такой мощи, что оно было удалено из игры и помещено на гигабайтную флэшку. «Зальцман из бухгалтерии» ранее предсказал, что меч когда-нибудь будет использован. Не зная об этом, ребята уже начали свой семнадцатичасовой крестовый поход против грифера, который, по догадкам Blizzard’а, будет наверняка безуспешным. Двое из них приходят в дом Стэна с флэшкой, не зная, что ребята играют в доме Картмана. Рэнди соглашается лично передать меч парням в игре; он долго ищет компьютер, в конце концов входит в игру с демо-компьютера в электронном магазине. Рэнди передаёт Стэну оружие, но сам оказывается смертельно ранен грифером. С помощью меча ребята уничтожают грифера перед тем, как персонаж Рэнди умирает.

  Игроки «World of Warcraft» празднуют гибель злодея. «И чем мы теперь займёмся?» — спрашивает Кайл. Картман говорит: «Теперь мы наконец-то сможем нормально поиграть».
  '''.split(' ')
  
  values = []
  
  while count: 
    values.append(' '.join(random.sample(words, random.randint(*length))))
    count -= 1
  if file_object is not None:
    file_object.write('\n'.join(values))
    return True
  return values


#@transaction.atomic
def import_item_titles(file_path):
  
  cat = Item('name').save()
  
  objects = []
  
  with open(file_path) as lines:	
    for line in lines:
      name = line.strip()
      translit = ' '.join(random.shuffle(generator(1, (3,4)) + name.split(' ')))
      slugified = ' '.join(random.shuffle(generator(1, (3,4)) + name.split(' ')))
      hash = hashlib.sha1(os.urandom(10000) + translit.encode('ascii')).hexdigest()
      urlencoded_name = quote_plus(name)
      urlencoded_translit = quote_plus(translit)

      k = ItemTitle(category=cat.pk,
            name=name,
            translit=translit,
            slugified=slugified,
            urlencoded_name=urlencoded_name,
            urlencoded_translit=urlencoded_translit,
            hash=hash
            )
      objects.append(k)

  ItemTitle.objects.bulk_create(objects)

if __name__ == '__main__':
  with open('for_example.data', 'w') as file_object:
    if generator(1000000, (5, 15), file_object):
      print('Success')
      
  import_item_titles('for_example.data')

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question