nobodynoone
@nobodynoone

Django — Как правильно использовать bulk_create?

Собственно сам вопрос в названии, а ниже приведен код, чтобы вы сами могли запустить и сказать что же я делаю не так.

Код, который приведен ниже съедает у меня 400мб оперативки и выполняется около 5 минут.
У меня windows 8.1 x64, python 3.4.1, mysql connector от 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')
  • Вопрос задан
  • 5842 просмотра
Пригласить эксперта
Ваш ответ на вопрос

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

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