Django: IntegrityError: column user_id не уникален
Я хотел проверить что-то, что использует объекты User.
Но по какой-то причине я получаю:
IntegrityError: column user_id is not unique
Я уже несколько секунд стучал головой о стену, и кажется, что я не могу понять, что не так. Сначала я подумал, что, возможно, база данных не размывается между тестами, но я отслеживал User.objects.all(), и это пустой список.
Это тест:
from django.contrib.auth.models import User
from django.test import TestCase
class TestSomething(TestCase):
def test_create_user(self):
User.objects.create_user('foo', '[email protected]', 'bar')
Мои настройки теста:
from settings import *
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': ':memory:',
}
}
TEST_RUNNER = 'django_nose.NoseTestSuiteRunner'
Update:
Я бы лучше прочитал мои следы соломы. Это фактически следующий сигнал, который вызывает проблему.
@receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
if created:
Profile(user=instance).save()
Ответы
Ответ 1
Я работал над проблемой, настраивая свой сигнал следующим образом:
from django.dispatch import receiver
@receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.get_or_create(user=instance)
Это решило симптом, но на самом деле не причина. Я думаю, что смешивание обычных тестов с Django-тестами приводит к ошибке. Когда я проверил тест только в моем вопросе, это сработает.
Если у меня нет других ответов, я буду отмечать это как правильно.
Ответ 2
Я столкнулся с той же проблемой и там было простое исправление. Проблема возникает, если вы запустите 'manage.py dumpdata', и у вас уже есть UserProfile в вашей базе данных. UserProfile будет находиться в json файле, поэтому, когда вы загружаете тестовый файл данных и пытаетесь создать новый новый UserProfile с тем же именем пользователя в своем тесте, вы получите конфликт, так как UserProfile с этим пользователем уже существует. Решение состоит в том, чтобы просто удалить UserProfile из json fixture.
Итак, в качестве примера:
- У вас есть существующая база данных с User с именем пользователя mathew и UserProfile, связанным с этим User
- Вы запустите файл manage.py dumpdatali >
- Теперь полученный json файл имеет в нем UserProfile, потому что он является частью ваших моделей приложений (но не для пользователя).
- Теперь вы пытаетесь создать пользователя в своем тесте следующим образом: 'User.objects.create_user (' mathew ',' [email protected] ',' password ')'
- Ваш сигнал сохранения сообщения будет срабатывать и попытаться создать UserProfile, связанный с User's mathew '
- Но этот UserProfile уже существует, поэтому вы получаете сообщение об ошибке
Надеюсь, что это поможет.
Ответ 3
Я полагаю, у вас есть поле user_id
с уникальным ограничением в модели профиля, не так ли?
Кажется, что вы пытаетесь сохранить профиль, связанный с одним и тем же объектом User, в каком-то другом месте вашего кода. get_or_create
ярлык работает отлично, потому что он создает новый объект, только если в базе данных нет такого объекта. В противном случае он возвращает существующий объект. С другой стороны, Profile(). Save() просто пытается сохранить объект и вызывает исключение, если это невозможно.
Это имеет смысл для вас?