Подтвердить что ты не робот

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()
4b9b3361

Ответ 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 dumpdata​​li >
  • Теперь полученный json файл имеет в нем UserProfile, потому что он является частью ваших моделей приложений (но не для пользователя).
  • Теперь вы пытаетесь создать пользователя в своем тесте следующим образом: 'User.objects.create_user (' mathew ',' [email protected] ',' password ')'
  • Ваш сигнал сохранения сообщения будет срабатывать и попытаться создать UserProfile, связанный с User's mathew '
  • Но этот UserProfile уже существует, поэтому вы получаете сообщение об ошибке

Надеюсь, что это поможет.

Ответ 3

Я полагаю, у вас есть поле user_id с уникальным ограничением в модели профиля, не так ли?

Кажется, что вы пытаетесь сохранить профиль, связанный с одним и тем же объектом User, в каком-то другом месте вашего кода. get_or_create ярлык работает отлично, потому что он создает новый объект, только если в базе данных нет такого объекта. В противном случае он возвращает существующий объект. С другой стороны, Profile(). Save() просто пытается сохранить объект и вызывает исключение, если это невозможно.

Это имеет смысл для вас?