Django Testing: нет данных во временном файле базы данных - PullRequest
4 голосов
/ 16 февраля 2012

Я использую базу данных sqlite3, настроенную следующим образом в settings.py:

DATABASES = {
    'default': {
        'ENGINE': 'django.contrib.gis.db.backends.spatialite',
        'NAME': 'path/to/config.sqlite',
        'TEST_NAME': 'path/to/test-config.sqlite',
        # ... USER, PASSWORD and PORT left out for brevity
    }
}

Во время пробного запуска началось с:

python manage.py test myapp.mytest

это временно создает файл базы данных path/to/test-config.sqlite, который мне нужен в другом приложении, загруженном необходимыми приборами.

Файл базы данных, однако, пуст, что я утверждал во время паузы в одном тесте:

sqlite> select * from someapp_somemodel;

... no results here :(

В других тестовых случаях, для которых не требуется файл sqlite и для которых достаточно базы данных в памяти, ошибок не возникает.

Мои вопросы:

  • Почему django не сбрасывает свои данные в файл базы данных, если он все равно его создает? и
  • Как мне убедить django сделать это, так как я требую, чтобы данные были сброшены во временный файл базы данных?

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

Я использую Django 1.3.1, если это интересно.

EDIT2

Я знаком с осветителями и использую их для заполнения базы данных, но моя проблема в том, что данные из осветителей не записываются в файл базы данных во время теста. Извините, если я не был достаточно ясен по этому факту.

EDIT3

Поскольку мой вопрос нуждается в пояснении, рассмотрите следующую настройку теста (которая близка к тому, что я на самом деле делаю):

class SomeTestCase(django.test.TestCase):
    fixtures = ["some_fixture.json", "some_other_fixture.json"]

    def testSomething(self):
        import pdb; pdb.set_trace()

Когда метод testSomething попадает в точку останова, я запускаю программу sqlite3 и подключаюсь к временному файлу базы данных, созданному Django. Приспособления загружены (что я знаю, потому что другие тесты работают хорошо), но данные не записываются во временный файл базы данных.

Ответы [ 5 ]

1 голос
/ 20 февраля 2012

Я нашел способ, но, поскольку я также испортил hdparm (с -F или -W 0/1), я не знаю, будет ли он работать для вас.Я сделал перезагрузку и еще раз, чтобы убедиться, что думал.Кроме того, этот тест не имеет SpatiaLite, но, как вы сказали, это, вероятно, не имеет значения.

В любом случае, нам нужно 2 экрана для его воспроизведения, screen0 запускает тесты и screen1 - оболочка sh для работы с волей Процесс screen0 приостановлен.

Запустить тест (screen0):

>>> ./manage.py test testapp
Creating test database for alias 'default'...
Destroying old test database 'default'...
Type 'yes' if you would like to try deleting the test database 'db_test.sqlite', or 'no' to cancel: yes
--Return--
None
> /home/jpic/testproject/testapp/tests.py(16)testSomething()
     14 
     15     def testSomething(self):
---> 16         import ipdb; ipdb.set_trace()

Проверьте размер созданного файла тестовой базы данных , (screen1):

<<< 18:00.39 Mon Feb 20 2012!~/testproject 
<<< jpic@germaine!10004 env
>>> ls -l db_test.sqlite
-rw-r--r-- 1 jpic jpic 49152 2012-02-20 18:00 db_test.sqlite

Запустите команду PRAGMA SYNCHRONOUS sql из python (screen0):

ipdb> from django.db import connection; cursor = connection.cursor()
ipdb> cursor.execute("PRAGMA SYNCHRONOUS")
<django.db.backends.sqlite3.base.SQLiteCursorWrapper object at 0x294f348>
ipdb> 

Проверьте, увеличился ли размер файла базы данных (screen1):

<<< 18:00.42 Mon Feb 20 2012!~/testproject 
<<< jpic@germaine!10005 env
>>> ls -l db_test.sqlite
-rw-r--r-- 1 jpic jpic 272384 2012-02-20 18:00 db_test.sqlite

Данные записаны в файл.

Это не имеет особого смысла для меня, потому что, очевидно, PRAGMA SYNCHRONOUS один должен просто запросить значение (в моем случае: 2 / FULL).Но на практике это записывает на диск.Обратите внимание, что если у вас нет 2 (FULL), вы должны установить его на 2: PRAGMA SYNCHRONOUS 2.

Теперь я не могу сказать что было написано (было написано полностью?) потому что я не могу заполучить тестовую базу данных: если я запускаю sqlite db_test.sqlite на screen1, чтобы получить клиента в тестовой базе данных: я не могу запустить ни одну команду (ни select, ни .dump), потому чтоMsgstr "Ошибка SQL: база данных заблокирована".Но, я думаю, это твоя проблема сейчас B)

1 голос
/ 20 февраля 2012

Похоже, вы что-то делаете с GeoDjango в зависимости от вашей базы данных, 'django.contrib.gis.db.backends.spatialite'.GeoDjango нуждается в дополнительной настройке, так что, я думаю, ему нужно что-то дополнительное для тестирования.(Если вы не используете GeoDjango, просто используйте 'django.db.backends.sqlite3' в качестве движка базы данных. Оставьте TEST_NAME, хотя в противном случае Django создаст тестовую БД в памяти.)

Существует целый процесс загрузки вПространственные данные и документы по установке GeoDjango очень подробны.Вот ссылка на создание базы данных SpatiaLite .Для тестирования вам понадобится в основном то же самое.

Из документов по тестированию :

Вам потребуется загрузить сценарий инициализации SQL для SpatiaLite.:

$ wget http://www.gaia-gis.it/spatialite/init_spatialite-2.3.zip

$ unzip init_spatialite-2.3.zip

Если init_spatialite-2.3.sql находится на том же пути, что и manage.py вашего проекта, тогда все, что вам нужно сделать, это: $ python manage.py test

1 голос
/ 19 февраля 2012

Возможно, это связано с как в тестах Django используются транзакции ?

Проверьте, сохраняется ли проблема, если вы отключите все транзакции в settings.py:

DISABLE_TRANSACTION_MANAGEMENT = True
1 голос
/ 20 февраля 2012

Из документации django :

... При использовании ядра базы данных SQLite тесты будут по умолчанию использовать база данных в памяти (то есть база данных будет создана в памяти, полностью обходя файловую систему!). Если вы хотите использовать другой имя базы данных, укажите TEST_NAME в словаре для любого данного база данных в DATABASES.

Кроме того, если вы прочитали о загрузке прибора :

... В начале каждого теста перед запуском setUp() Django очищает базу данных, возвращая базу данных в состояние, в котором она находилась непосредственно после вызова syncdb ...

Если вам нужна свежая база данных с несколькими загруженными приборами, вы, конечно, можете сделать это, создав пустую базу данных с запущенным syncdb и загрузив некоторые приборы с помощью django-admin.py loaddata!

1 голос
/ 19 февраля 2012

Запустили ли вы исходный syncdb для создания таблиц базы данных? ( python yourproject / manage.py syncdb )

В вашем файле settings.py какие приложения вы установили в INSTALLED_APPS?

Какие модели вы построили в своем проекте?

В зависимости от того, какие приложения вы установили в INSTALLED_APPS и какие пользовательские модели вы добавили в свой проект, будет диктоваться, какие базы данных создаст syncdb.

...