Как запустить тестовую базу данных Django только в памяти?



мои модульные тесты Django занимают много времени, поэтому я ищу способы ускорить это. Я рассматриваю возможность установки SSD, но я знаю, что есть и свои минусы тоже. Конечно, есть вещи, которые я мог бы сделать с моим кодом, но я ищу структурное исправление. Даже запуск одного теста выполняется медленно, так как база данных должна быть перестроена / перенесена на юг каждый раз. Итак, вот моя идея...



поскольку я знаю, что тестовая база данных всегда будет довольно маленькой, почему я не могу просто настроить систему так, чтобы вся тестовая база данных всегда находилась в оперативной памяти? Никогда не прикасайтесь к диску вообще. Как настроить это в Django? Я бы предпочел продолжать использовать MySQL так как это то, что я использую в производстве, но если SQLite 3 или что-то еще делает это легко, я бы пошел этим путем.



есть ли у SQLite или MySQL возможность работать полностью в памяти? Должна быть возможность настроить диск и настроить тестовую базу данных для хранения данных, но Я не уверен, как сказать Django / MySQL использовать другой каталог данных для определенной базы данных, тем более, что он продолжает стираться и воссоздаваться при каждом запуске. (Я нахожусь на Mac FWIW.)

644   7  

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

он имеет два преимущества:

  1. вам не нужно проверять test или любое такое волшебное слово в sys.аргв,test_settings.py можно просто

    from settings import *
    
    # make tests faster
    SOUTH_TESTS_MIGRATE = False
    DATABASES['default'] = {'ENGINE': 'django.db.backends.sqlite3'}
    

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

  2. другое преимущество заключается в том, что вы можете запустить тест с производства 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

    Ничего не найдено.