Найти - Пользователи
Полная версия: Django - Как правильно создавать экземпляры класса для bulk_create?
Начало » Django » Django - Как правильно создавать экземпляры класса для bulk_create?
1
kise97
Привет.

Мне нужно импортировать больше миллиона записей в БД, вес файла с этими данными больше 400Мб.

Я решил сделать примерно так:

# python 3
# models.py 
class Item(models.Model):
    name1 = models.TextField()
    name2 = models.TextField()
    name3 = models.TextField()
    name4 = models.TextField()
    name5 = models.TextField()
    name6 = models.TextField()
    name7 = models.TextField()
    name8 = models.CharFiled(max_length=150, unique=True)
# action
with open('items.txt') as file_object: 
    items = []
    for line in file_object:
        item_data = line.strip().split(';')
        i = Item(
            name1=item_data[0],
            name2=item_data[1],
            name3=item_data[2],
            name4=item_data[3],
            name5=item_data[4],
            name6=item_data[5],
            name7=item_data[6],
            name8=item_data[7],
            name9=item_data[8],
        )
        items.append(i)
        if len(items) > 900: 
            Item.objects.bulk_create(items)
            del items[:]


Т.е. вы можете заметить такой алгоритм: я читаю файл по строчно, извлекаю информацию из строки, создаю экземпляр класса, далее добавляю его в переменную, после этого проверяю, сколько в переменной записей, если больше 900, то я вызываю bulk_create и очищаю массив… Но даже так этот скрипт пожирает больше 300Мб.

Помимо этого, я столкнулся с ошибкой

django.db.utils.DatabaseError: Lost connection to MySQL server at ‘127.0.0.1:3306’, system error: 10054

Которая появилась, когда я делал примерно вот так

# python 3
# models.py 
class Item(models.Model):
    name1 = models.TextField()
    name2 = models.TextField()
    name3 = models.TextField()
    name4 = models.TextField()
    name5 = models.TextField()
    name6 = models.TextField()
    name7 = models.TextField()
    name8 = models.CharFiled(max_length=150, unique=True)
# action
items = []
with open('items.txt') as file_object: 
    for line in file_object:
        item_data = line.strip().split(';')
        i = Item(
            name1=item_data[0],
            name2=item_data[1],
            name3=item_data[2],
            name4=item_data[3],
            name5=item_data[4],
            name6=item_data[5],
            name7=item_data[6],
            name8=item_data[7],
            name9=item_data[8],
        )
        items.append(i)
Item.objects.bulk_create(items)


Почему появлялась эта ошибка и как можно бороться с прожорливостью python`а?
FishHook
Ну и зачем? База на локалхосте, траффик экономить не надо, время работы скрипта не критично.
Брось эту затею и пиши в базу просто построчно.
bulk_create в джанге - это сам по себе еще тот геморрой. Например, он не работает с ораклом. А какой чудесный запрос создает этот замечательный метод! А пользы от него мало. На практике замечено, что скорость обработки запросов по одному и то же балк_криэйтом различается несущественно, а иногда и в пользу действия в лоб.
kise97
Нет, как раз таки такой функционал нужен на продакшене.. это часть сайта.
Построчно это больше миллиона записей, а это ой как много.

Вот например в SQLAlchemy есть потрясающая вещь `add_all()`, которая такой проблемой не обладает и загружала все а базу примерно за 2-3 минуты, я хочу сделать тоже самое и в джанге…
FishHook
kise97
Построчно это больше миллиона записей, а это ой как много.
Я тебя умоляю, для нормальной базы миллион записей - это только фикстуры подгрузить.
kise97
Если добавлять по одной записи, то скрипт работает в районе 20 минут. Это просто нереально много, даже на php у меня подобное работает всего за 3-4 минуты.

Хотя нет, на php у меня была немного другая задача, но да, там примерно 2-3 млн добавлялось за 2-3 минуты.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB