Работать с “пустой” базой данных неудобно. Поэтому, при настройке и отладке приложения часто возникает необходимость в “начальных” данных для проекта. Django предлагает нам ряд возможностей для автоматического создания таких данных: с помощью файлов предварительной настройки (fixtures), либо с помощью SQL запросов.
В общем, подход с использованием файлов с данными является более “чистым”, поскольку он учитывает специфику конкретной базы данных, но использование SQL запросов дает немного больше гибкости.
Файлы предварительной настройки (fixtures) содержат набор данных, которые Django может импортировать в базу данных. Самый простой путь создания таких файлов (при условии что ваша база данных уже содержит некоторую нужную информацию) это использование команды manage.py dumpdata. Вы также может создать данные “вручную” используя синтаксис XML, YAML(при установленном PyYAML) или JSON и сохранив результат в соответствующем формате. В разделе сериализация данных более детально описан каждый из поддерживаемых форматов. (Прим. пер. : существуют дополнения, которые могут помочь в создании файлов настроек, н-р, пакет django-fixture-magic)
Н-р, ниже представлено содержимое такого файла в формате JSON для простой модели Person:
[
{
"model": "myapp.person",
"pk": 1,
"fields": {
"first_name": "John",
"last_name": "Lennon"
}
},
{
"model": "myapp.person",
"pk": 2,
"fields": {
"first_name": "Paul",
"last_name": "McCartney"
}
}
]
А вот те же данные в формате YAML:
- model: myapp.person
pk: 1
fields:
first_name: John
last_name: Lennon
- model: myapp.person
pk: 2
fields:
first_name: Paul
last_name: McCartney
Что-бы данные “заработали”, создайте папку fixtures в папке приложения и сохраните в ней файлы с данными. ( Прим. пер. : имя fixtures предопределено в Django, и в случае опечатки в названии - данные не будут найдены!)
Загрузить данные просто: выполните команду manage.py loaddata <fixturename>, где <fixturename> это имя созданного вами файла с данными. Каждый раз при запуске loaddata, данные будут считываться из файлов и записываться в базу данных. Обратите внимание, вы можете изменить загруженные начальные данные в процессе работы, но при следующем вызове loaddata все изменения будут утеряны.
Не рекомендуется, начиная с версии 1.7: Если приложение использует миграции, фикстуры не будут автоматически загружаться. Т.к. миграции будут обязательны в Django 1.9, автоматически загружаемые фикстуры считаются устаревшими. Если вам необходимо загрузить начальные данные для приложения, используйте миграцию данных.
Если создать файл предварительной настройки с именем initial_data.[xml/yaml/json], то он будет загружен автоматически при каждом запуске migrate. Конечно это очень удобно, но стоит помнить, что данные будут обновляться каждый раз при запуске migrate, поэтому лучше не использовать initial_data с данными, которые вы планируете редактировать. (Прим. пер. : если автозагрузку надо временно “отключить”, то удобно просто добавить символ нижнего подчеркивания перед initial_data).
По умолчанию Django ищет и “просматривает” папки fixtures внутри папки с приложением. Вы можете немного изменить это поведение, указав в настройках проекта FIXTURE_DIRS список дополнительных директорий для поиска.
При запуске manage.py loaddata, вы можете указать абсолютный путь к файлу с данными, “отменив” тем самым механизм поиска по умолчанию.
См.также
Предварительная настройка данных также используется в тестировании для создания и настройки среды для тестирования.
Не рекомендуется, начиная с версии 1.7: Если приложение использует миграции, начальные SQL данные не будут загружаться. Т.к. миграции будут обязательны в Django 1.9, автоматически загружаемые фикстуры считаются устаревшими. Если вам необходимо загрузить начальные данные для приложения, используйте миграцию данных.
В Django есть возможность “перехватить” выполнение инструкции CREATE TABLE командой migrate и передать базе данных произвольные инструкции SQL для выполнения. Мы можем использовать этот “трюк” чтобы заполнить записями таблицы базы данных, или создать SQL функции, отображения, триггеры и т.д.
“Трюк” не сложен: Django просматривает каталог приложения и ищет файл с именем sql/<modelname>.sql, где <modelname> - имя модели в нижнем регистре.
Таким образом, н-р, если у вас есть модель Person в приложении myapp, вы можете добавить произвольные запросы SQL в файл sql/person.sql, который должен находится в папке myapp. Вот пример того, что такой файл может содержать:
INSERT INTO myapp_person (first_name, last_name) VALUES ('John', 'Lennon');
INSERT INTO myapp_person (first_name, last_name) VALUES ('Paul', 'McCartney');
Каждый SQL файл (если найден) должен содержать корректные инструкции SQL, которые запишут желаемые данные (т.е. , инструкции INSERT без ошибок в форматировании, разделенные точкой с запятой)
Файлы SQL считываются командами sqlcustom и sqlall из manage.py. За дополнительной информацией обратитесь к документация по manage.py.
Обратите внимание, что если имеется несколько файлов с данными в виде SQL, то очередность их выполнения не регламентируется. Так что, единственное предположение которое можно сделать, - что к моменту выполнения пользовательских инструкций SQL из файлов, все таблицы базы данных должны быть уже созданы.
Начальные SQL данные и тестирование
Такой подход нельзя использовать для тестирования приложений, поскольку тестовая среда Django очищает содержимое тестовой базы данных после каждого теста; как результат, - любые данные добавленные с помощью пользовательских запросов SQL будут утеряны.
Если вам нужны начальные данные для тестирования, вы можете воспользоваться либо файлами предварительной настройки для тестирования (test fixture), либо создать необходимые данные программным путем в методе setUp() тестового модуля.
Возможность создать начальные данные с помощью запросов SQL учитывает также и специфику бэкэнда. Например, можно иметь несколько независимых файлов, инициализирующих данные, для PostgreSQL и SQLite. Для каждого приложения, Django проверит наличие файла вида <app_label>/sql/<modelname>.<backend>.sql, где <app_label> - каталог приложения, <modelname> - имя модели в нижнем регистре, <backend> - последняя часть от имени модуля, указанного в ENGINE в файле настроек. (т.е., если вы указали базу данных в настройках в ENGINE со значением django.db.backends.sqlite3, Django будет искать файл с именем <app_label>/sql/<modelname>.sqlite3.sql).
Данные SQL, специфичные для конкретного типа базы данных имеют приоритет над данными, где такая специфика не указана. Н-р, если приложение содержит файлы sql/person.sql и sql/person.sqlite3.sql и вы используете в качестве бэкенда SQLite, то Django выполнит первыми инструкции из sql/person.sqlite3.sql, а затем из sql/person.sql.
Jun 02, 2016