Увеличение идентификаторов объектов django между юнит-тестами - PullRequest
5 голосов
/ 06 июня 2011

Я использую Django 1.2.3-3 + squeeze1 на Debian squeeze с PostgreSQL 8.4.7-0squeeze2 (хотя я не думаю, что PostgreSQL здесь уместен) и запускаю модульные тесты Django на основе unittest со следующим setUp and tearDown

   def setUp(self):
        print "running setup"
        self.c = Client()
        self.user = User.objects.create_user('faheem', 'faheem@email.unc.edu', 'foo')
        self.logged_in = self.c.login(username='faheem', password='foo')
        settings.MEDIA_ROOT='/tmp/'
        #settings.ZIP_UPLOAD='/var/tmp/zip/'

    def tearDown(self):
        print "running teardown"
        FolderUpload.objects.all().delete()
        FileUpload.objects.all().delete()
        ZipFileUpload.objects.all().delete()
        OldFileUpload.objects.all().delete()
        # FIXME: Quick & dirty fix for the time being. Should make this a delete method.
        os.system("rm -rf "+ settings.ZIP_UPLOAD + "/*")

Идея состоит в том, чтобы все было удалено из базы данных между выполнением модульных тестов. Согласно документации для тестирования, для этого tearDown. Проблема, с которой я столкнулся, заключается в том, что между различными модульными тестами все еще сохраняется какое-то состояние. В частности, я вижу, что идентификаторы увеличиваются. Допустим, если я создаю один ZipFileUpload объект в test1, а затем создаю один ZipFileUpload объект в test2, то я ожидаю, что оба идентификатора будут 1, но я вижу, что это id 1 для test1 и id 2 для test2. Это имело бы смысл, если бы идентификаторы исходили из некоторого индекса, который находится за пределами этих таблиц. Я не знаю достаточно о том, как Дианго делает это, чтобы знать, так ли это на самом деле. Если они делают это таким образом, я понятия не имею, почему. Будем признательны за любые разъяснения по этому вопросу.

Несмотря ни на что, я бы согласился на чистый способ отбросить базу данных, если кто-нибудь может предложить один. Этот метод, вероятно, должен идти в teadDown. Тестирование приложений Django упоминает следующую функцию, но мне не удалось импортировать ее из django.test.utils. Смущает, эта функция, кажется, в django/db/backends/creation.py.

destroy_test_db (old_database_name, verbosity = 1)

Уничтожает базу данных, имя которой хранится в NAME в БАЗАХ ДАННЫХ, и устанавливает NAME для использования предоставленного имени.

Первая часть этого предложения «Хорошо» - «Уничтожить базу данных, имя которой хранится в NAME в БАЗАХ ДАННЫХ», но что подразумевается под "устанавливает NAME для использования предоставленного имени"? Я предполагаю, что предоставленное имя old_database_name,

Непонятно, что такое NAME в контексте. Это NAME в DATABASES, и если да, зачем мне устанавливать то, что уже установлено? Я предполагаю, что предоставленное имя old_database_name, но если это так, зачем мне устанавливать аргумент old_database_name? Это предложение без изменений в документах по разработке.

РЕДАКТИРОВАТЬ:

После ответа Стива Мейна (см. Ниже) я подумал, что немного подробнее остановлюсь на этом.

Это приложение было изначально написано более 2007/2008/2009, включая юнит-тесты. В течение большей части этого времени я использовал Django до версии 1.0. Согласно Django Release History Кена Кохрана , 1.0 был выпущен 3 сентября 2008 года. Описанная установка работала нормально в течение этого времени. Я вижу, что функция tearDown выше была изначально написана в декабре 2007 года. Так что, возможно, поведение Django изменилось?

Оглядываясь назад, я понимаю, что очистка таблиц, как это делает tearDown выше, не гарантирует, что счетчик идентификаторов будет сброшен до 1, поскольку последовательность может быть отдельным объектом от таблицы.

Спасибо Стиву за его решение. Если он существует, я хотел бы услышать о портативном решении для сброса последовательности. Мне также было бы интересно узнать, как заставить работать destroy_test_db функцию выше.

1 Ответ

5 голосов
/ 06 июня 2011

Вы можете сбросить последовательность идентификаторов в каждой таблице, используя следующий SQL:

SELECT pg_catalog.setval(pg_get_serial_sequence('table_name', 'id'), 1);

Это следует делать только в том случае, если ваша таблица пуста.

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