Сбой тестов Django после перехода на 1.2.5 - проблема первичного ключа для дочерней модели - PullRequest
3 голосов
/ 05 апреля 2011

У меня есть модель ThreadedComment, которая наследуется от модели Object. ThreadedComment не имеет собственного уникального первичного ключа, полагаясь на первичный ключ объекта («ID»). Вот как строится модель:

class Object(models.Model):
    permalink = models.CharField(max_length=128)
    status = models.IntegerField()
    version = models.IntegerField()

class ThreadedComment(Object):
    parent = models.ForeignKey('self', null=True, blank=True, default=None, related_name='children')
    parent_object = models.OneToOneField(Object, parent_link=True)
    # other fields follow

Это прекрасно работало до django 1.2.3, но когда я обновился до django 1.2.5 (у 1.3 такая же проблема), это происходит, когда я пытаюсь запустить любой тест:

Error: Database test_db couldn't be flushed. Possible reasons:
  * The database isn't running or isn't configured correctly.
  * At least one of the expected database tables doesn't exist.
  * The SQL was invalid.
Hint: Look at the output of 'django-admin.py sqlflush'. That's the SQL this command wasn't able to run.
The full error: relation "threadedcomments_threadedcomment_id_seq" does not exist
LINE 1: SELECT setval('"threadedcomments_threadedcomment_id_seq"', 1...

Проблема в команде sqlflush, которая генерирует и выполняет файл SQL. Проблемная строка:

SELECT setval(pg_get_serial_sequence('"threadedcomments_threadedcomment"','id'), 1, false);

Это явно не сработает, поскольку в этой таблице нет столбца "id".

Что интересно, версия django 1.2.3 выдает похожий вывод:

SELECT setval('"threadedcomments_threadedcomment_id_seq"', 1, false);

но тест все равно продолжается, поэтому я раньше не замечал этой проблемы.

Что я здесь не так делаю? Является ли определение модели неверным, то есть мне нужен первичный ключ в потоке комментария, даже если мне не нужно, чтобы он имел отношение один к одному с объектом? И почему все работало нормально с 1.0 до 1.1 до 1.2.3, а теперь ломается в 1.2.5?

Ответы [ 3 ]

4 голосов
/ 19 апреля 2011

Это оказалось ошибкой в ​​django.Подробности здесь: http://code.djangoproject.com/ticket/12728

А вот наш временный обходной путь: https://bitbucket.org/filmaster/filmaster-test/changeset/afbac905cf63

0 голосов
/ 06 апреля 2011

Вы сказали: «ThreadedComment не имеет собственного уникального первичного ключа, полагаясь на promary [sic] ключ Object ('ID')".Django требует, чтобы одно поле было идентифицировано как первичный ключ.См. Поля автоматического первичного ключа .

Подробнее.,.

Функция pg_get_serial_sequence () возвращает имя последовательности, используемой конкретным столбцом.Таким образом, следующее утверждение означает: «Получить имя последовательности, используемой для столбца« id »в таблице« threadadedcomments_threadedcomment », установить поле last_value последовательности в« 1 »и вернуть 1 при следующем вызове nextval ().

SELECT setval(pg_get_serial_sequence('"threadedcomments_threadedcomment"','id'), 1, false);

Но это утверждение

SELECT setval('"threadedcomments_threadedcomment_id_seq"', 1, false);

означает: «Установите в поле last_value последовательности с именем 'threadadedcomments_threadedcomment_id_seq' значение 1 и верните 1 при следующем вызове nextval ()."

Я предполагаю, что алгоритм, используемый Django для именования последовательностей, изменяемых между версиями. Я видел, как другие системы вносили подобные изменения, потому что идентификаторы, созданные путем объединения имен таблиц и столбцов, стали слишком длинными. Я думаю, что идентификаторы Oracle имеют 30-ограничение по количеству символов; ваш идентификатор составляет 39 символов. Я видел, как Rails генерирует 70+ идентификаторов символов, которые нарушаются в PostgreSQL (ограничение 63 или 64 символа).

0 голосов
/ 06 апреля 2011

Я не могу воспроизвести его на стволе или 1.2.3;Я создал новый проект с приложением "threadadedcomments" и моделями, которые вы разместили, со следующим результатом:

BEGIN;
TRUNCATE "threadedcomments_threadedcomment", "auth_permission", "auth_group", "auth_group_permissions", "django_session", "auth_user_groups", "auth_user_user_permissions", "threadedcomments_object", "auth_message", "django_site", "auth_user", "django_content_type";
SELECT setval(pg_get_serial_sequence('"auth_permission"','id'), 1, false);
SELECT setval(pg_get_serial_sequence('"auth_group"','id'), 1, false);
SELECT setval(pg_get_serial_sequence('"auth_user"','id'), 1, false);
SELECT setval(pg_get_serial_sequence('"auth_message"','id'), 1, false);
SELECT setval(pg_get_serial_sequence('"django_content_type"','id'), 1, false);
SELECT setval(pg_get_serial_sequence('"django_site"','id'), 1, false);
SELECT setval(pg_get_serial_sequence('"threadedcomments_object"','id'), 1, false);
COMMIT;

Sequence threadedcomments_threadedcomment_id_seq никогда не создается, и Django не пытается его сбросить.Я не думаю, что это ошибка, связанная с изменением версии (скорее, она была всегда, но оставалась незамеченной).

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