НЕТ, get_or_create не атомарный .
Сначала запрашивается DB, существует ли удовлетворительная строка;база данных возвращается, Python проверяет результаты;если он не существует, он создает его.Между get
и create
может произойти все что угодно - и строка, соответствующая критериям get
, будет создана каким-то другим кодом.
Например, в отношении вашей конкретной проблемы, если две страницы открытыпользователем (или выполняется несколько запросов ajax) одновременно, это может привести к сбою всех get
, и для всех них create
новая строка - с одним и тем же сеансом.
Itпоэтому важно использовать get_or_create
только тогда, когда проблема дублирования будет обнаружена базой данных через некоторые unique
/ unique_together
, так что даже если несколько потоков могут добраться доточка save (), только одна будет успешной, а другие вызовут ошибку IntegrityError, с которой вы можете поймать и справиться.
Если вы используете get_or_create
с (набором) полей, которые не являются уникальнымив базе данных вы создадите дубликаты в своей базе данных, что редко является тем, что вам нужно.
В целом: не полагайтесь на свое приложение для обеспечения уникальности и избегайте дубликатов в вашей базе данных!Это работа с базой данных!(хорошо, если вы не заключите свои критические функции в некоторые блокировки, действительные для ОС, но я все равно рекомендую использовать базу данных).
При правильном использовании предупреждений get_or_create
легко читается, легко пишетсяконструкция, которая идеально дополняет проверки целостности базы данных.
Ссылки и цитаты: