У меня есть несколько статических таблиц, которые я инициализирую с помощью команды управления.
Suit(name = "Clubs").save()
Suit(name = "Hearts").save()
Suit(name = "Diamonds").save()
Suit(name = "Spades").save()
Я хочу иметь возможность повторно запустить это в любое время, если появятся новые значения, но я хочу избежать вставки дубликатов. База данных имеет уникальное ограничение, поэтому при наличии дубликатов я получаю сообщение об ошибке. Помимо упаковки каждого отдельного оператора в try/catch, есть ли способ запустить несколько таких операторов, игнорировать нарушение ограничений и продолжать работу?
Вместо того, чтобы звонить .save()
, я бы позвонил .get_or_create()
, как описано здесь.
Suit.objects.get_or_create(name = "Clubs")
Suit.objects.get_or_create(name = "Hearts")
Suit.objects.get_or_create(name = "Diamonds")
Suit.objects.get_or_create(name = "Spades")
у нас обоих один и тот же ответ 😅
Спасибо. это именно то, что я искал. Извините, что не могу принять оба ответа :-)
Либо вы можете использовать метод @deceze, который уже упоминался, то есть использовать список и try-except
.
или вы можете использовать метод get_or_create
Удобный метод поиска объекта по заданным кваргам (может быть пустым, если в вашей модели есть значения по умолчанию для всех полей), создание объекта при необходимости.
for ele in lst: # the list of data
Suit.objects.get_or_create(ele)
Если количество объектов (здесь четыре) невелико, мы можем работать с .get_or_create(…) [Django-doc]. Однако это не будет хорошо масштабироваться, если мы загрузим ~100 или более элементов в базу данных, поскольку это приведет как минимум к ~100 запросам.
В этом случае мы можем работать с двумя запросами: сначала посмотреть, какие элементы уже есть в базе данных, а затем вставить недостающие в один запрос, например:
items = [
('Clubs',),
('Hearts',),
('Diamonds',),
('Spades',),
]
field_names = ('name',)
model = Suit
existing = set(model._base_manager.values_list(*field_names))
model._base_manager.bulk_create(
[
model(**dict(zip(field_names, item)))
for item in items
if item not in existing
]
)
Его также можно использовать с другими полями, например:
model = Card
item = [
('Spades', 4),
]
field_names = ('kind', 'value')
Поскольку код идентичен, за исключением фактических значений, составьте список значений и напишите один цикл с одним
try..except
…?