Как запустить тестовую базу данных Django только в памяти?
мои модульные тесты Django занимают много времени, поэтому я ищу способы ускорить это. Я рассматриваю возможность установки SSD, но я знаю, что есть и свои минусы тоже. Конечно, есть вещи, которые я мог бы сделать с моим кодом, но я ищу структурное исправление. Даже запуск одного теста выполняется медленно, так как база данных должна быть перестроена / перенесена на юг каждый раз. Итак, вот моя идея...
поскольку я знаю, что тестовая база данных всегда будет довольно маленькой, почему я не могу просто настроить систему так, чтобы вся тестовая база данных всегда находилась в оперативной памяти? Никогда не прикасайтесь к диску вообще. Как настроить это в Django? Я бы предпочел продолжать использовать MySQL так как это то, что я использую в производстве, но если SQLite 3 или что-то еще делает это легко, я бы пошел этим путем.
есть ли у SQLite или MySQL возможность работать полностью в памяти? Должна быть возможность настроить диск и настроить тестовую базу данных для хранения данных, но Я не уверен, как сказать Django / MySQL использовать другой каталог данных для определенной базы данных, тем более, что он продолжает стираться и воссоздаваться при каждом запуске. (Я нахожусь на Mac FWIW.)
7 ответов:
если вы установите компонент database engine в sqlite3 при выполнении тестов,Django будет использовать базу данных в памяти.
я использую такой код в моем
settings.pyчтобы установить двигатель на sqlite при выполнении моих тестов:if 'test' in sys.argv: DATABASE_ENGINE = 'sqlite3'или в Django 1.2:
if 'test' in sys.argv: DATABASES['default'] = {'ENGINE': 'sqlite3'}и, наконец, в Django 1.3 и 1.4:
if 'test' in sys.argv: DATABASES['default'] = {'ENGINE': 'django.db.backends.sqlite3'}(полный путь к бэкэнду не является строго необходимым с Django 1.3, но делает настройку вперед совместимый.)
вы также можете добавить следующую строку, если у вас возникли проблемы с Южной миграцией:
SOUTH_TESTS_MIGRATE = False
обычно я создаю отдельный файл настроек для тестов и использую его в команде test, например
python manage.py test --settings=mysite.test_settings myappон имеет два преимущества:
вам не нужно проверять
testили любое такое волшебное слово в sys.аргв,test_settings.pyможно простоfrom settings import * # make tests faster SOUTH_TESTS_MIGRATE = False DATABASES['default'] = {'ENGINE': 'django.db.backends.sqlite3'}или вы можете дополнительно настроить его для ваших нужд, чисто отделяя настройки тестирования от производственных настроек.
другое преимущество заключается в том, что вы можете запустить тест с производства Database engine вместо sqlite3 избегает тонких ошибок, поэтому при разработке используйте
python manage.py test --settings=mysite.test_settings myappи перед фиксацией кода запустите один раз
python manage.py test myappпросто чтобы убедиться, что все испытания действительно проходят.
MySQL поддерживает механизм хранения под названием "Память", который можно настроить в конфигурации базы данных (
settings.py) так:'USER': 'root', # Not used with sqlite3. 'PASSWORD': '', # Not used with sqlite3. 'OPTIONS': { "init_command": "SET storage_engine=MEMORY", }обратите внимание, что механизм хранения памяти не поддерживает столбцы blob / text, поэтому если вы используете
django.db.models.TextFieldэто не будет работать для вас.
Я не могу ответить на ваш главный вопрос, но есть несколько вещей, которые вы можете сделать, чтобы ускорить события.
во-первых, убедитесь, что ваша база данных MySQL настроена на использование InnoDB. Затем он может использовать транзакции для отката состояния БД перед каждым тестом, что, по моему опыту, привело к массовому ускорению. Вы можете передать команду инициализации базы данных в свой settings.py (синтаксис Django 1.2):
DATABASES = { 'default': { 'ENGINE':'django.db.backends.mysql', 'HOST':'localhost', 'NAME':'mydb', 'USER':'whoever', 'PASSWORD':'whatever', 'OPTIONS':{"init_command": "SET storage_engine=INNODB" } } }во-вторых, вам не нужно запускать южные миграции каждый время. Набор
SOUTH_TESTS_MIGRATE = Falseв вашем settings.py и база данных будет создана с помощью простого syncdb, что будет намного быстрее, чем выполнение всех исторических миграций.
вы можете сделать двойной настройки:
- использовать транзакционные таблицы: начальное состояние светильников будет установлено с помощью отката базы данных после каждого тестового случая.
- поместите свой каталог данных базы данных на ramdisk: вы получите многое, что касается создания базы данных, а также запуск теста будет быстрее.
Я использую оба трюка, и я вполне доволен.
Как настроить его для MySQL на Ubuntu:
$ sudo service mysql stop $ sudo cp -pRL /var/lib/mysql /dev/shm/mysql $ vim /etc/mysql/my.cnf # datadir = /dev/shm/mysql $ sudo service mysql startосторожно, это только для тестирование, после перезагрузки вашей базы данных из памяти теряется!
другой подход: есть еще один экземпляр MySQL, работающий в tempfs, который использует RAM-диск. Инструкции в этом блоге:ускорение MySQL для тестирования в Django.
плюсы:
- вы используете точно такую же базу данных, что и ваш рабочий сервер
- нет необходимости изменять конфигурацию mysql по умолчанию
расширяя ответ Анурага, я упростил процесс, создав те же test_settings и добавив следующее manage.py
if len(sys.argv) > 1 and sys.argv[1] == "test": os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.test_settings") else: os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")кажется чище, так как sys уже импортирован и manage.py используется только через командную строку, поэтому не нужно загромождать настройки
Comments