Массовое создание для моделей с внешним ключом

У меня есть эти две модели:

class Item(models.Model):
    item_id = models.CharField(max_length=10, primary_key=True)
    item_name = models.CharField(max_length=100)
    description = models.CharField(max_length=500)
    slug = models.CharField(max_length=200)
    price = models.FloatField()
    
    def __str__(self):
        return self.item_name
class Image(models.Model):
    item = models.ForeignKey(Item, on_delete=models.CASCADE)
    image_url = models.CharField(max_length=200)

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

Чтобы добавить элементы в базу данных, я делаю это через массовое создание:

    it = (Item(
            item_id = item['id'],
            item_name= item['title'],
            description = item['description'],
            slug = item['slug'],
            price =  item['price']['amount']
            )
        for item in items
    )
    while True:
        batch = list(islice(it, batch_size))
        if not batch:
            break
        Item.objects.bulk_create(batch, batch_size)

Это работает прекрасно, хорошо. Но я хочу сделать то же самое с изображениями, поскольку у меня слишком много изображений, чтобы делать это по отдельности.

На данный момент я делаю это следующим образом:

for item in items:
    for image in item['images']:
        Item.objects.get(item_id = item['id']).image_set.create(image_url = image['urls']['big'])

Но это слишком медленно для загрузки всех изображений (это может занять 30 минут), поэтому я хочу загрузить их оптом, как я это делаю с Item, но поскольку модель Image имеет Item в качестве внешнего ключа, я не могу сделать это тем же способом. Как я могу загрузить изображения более эффективным способом?

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

Спасибо.

Вы также можете создавать Image объекты в большом количестве, используя:

images = [
    Image(item_id=item['id'], image_url=image['urls']['big'])
    for item in items
    for image in item['images']
]
Image.objects.bulk_create(images)

Здесь мы используем item_id=item['id'], чтобы установить значение для ForeignKey позже, а затем вставляем все это в базу данных.

Это работает, потому что если вы определяете поле с именем fieldname как ForeignKey, Django позволяет вам работать с fieldname_id, чтобы указать значение для поля to, на которое ссылается это ForeignKey.

Вернуться на верх