Я использую модели многотабличного наследования.
from django.db import models
class Place(models.Model):
name = models.CharField(max_length=50)
address = models.CharField(max_length=80)
class Restaurant(Place):
serves_hot_dogs = models.BooleanField(default=False)
serves_pizza = models.BooleanField(default=False)
class Cinema(Place):
sells_tickets = models.BooleanField(default=False)
sells_popcorn = models.BooleanField(default=False)
class Coffee(Place):
sells_tea = models.BooleanField(default=False)
У меня есть представление, которое создает несколько разных моделей:
items = [
Restaurant(...),
Restaurant(...),
Restaurant(...),
Cinema(...),
Cinema(...),
Coffee(...),
Coffee(...),
# + 1.000 other items
]
for item in items:
item.save()
Очевидно, что это действительно неэффективно, поскольку создает много запросов. К сожалению, Django пока не предоставляет метод массового создания для наследования нескольких таблиц (для этого есть open pull request). Как лучше всего оптимизировать этот код? Должен ли я писать необработанный SQL-запрос или есть другой способ?
@harshilsuthar Пожалуйста, прочитайте вопрос полностью. OP уже заявил, что изучил свои варианты и что bulk_create не работает для его варианта использования.
Я решил это, проверив реализацию bulk_create . В основе этого лежит класс InsertQuery для генерации оператора SQL INSERT INTO
. ИМХО, это намного чище и короче, чем написание необработанного SQL-запроса.
# Create all concrete models at once
items = Place.objects.bulk_create(items)
# Group items by their model
item_mapping = defaultdict(list)
for item in items:
item_mapping[type(item)].append(item)
# Create a bulk insert for each model
for model, items in item_mapping.items():
fields = model._meta.local_concrete_fields
query = sql.InsertQuery(model)
query.insert_values(fields, items)
query.get_compiler(connection=connection).execute_sql()
Привет. Работает только для PostgreSQL, потому что другие механизмы баз данных не возвращают объекты со сгенерированными первичными ключами в качестве возврата от bulk_create. Это будет работать, только если вы явно определите первичный ключ для родительской модели и обработаете первичные ключи вручную.
обратитесь к этому docs.djangoproject.com/en/3.1/ref/models/querysets/#bulk-create