• 3.1
  • 3.2
  • 5.0
  • Версия документации: 6.1

Фикстуры

Фикстура — это набор файлов, содержащих сериализованное содержимое базы данных. Каждый прибор имеет уникальное имя, а файлы, составляющие прибор, могут быть распределены по нескольким каталогам в нескольких приложениях.

Как изготовить приспособление

Фикстуры могут быть созданы с помощью manage.py dumpdata. Также возможно создавать собственные фикстуры, используя инструменты сериализации или даже написав их от руки.

Как пользоваться приспособлением

Фикстуры можно использовать для предварительного заполнения базы данных данными для tests:

class MyTestCase(TestCase):
    fixtures = ["fixture-label"]

или предоставить некоторые начальные данные с помощью команды loaddata:

django-admin loaddata <fixture label>

Как обнаруживаются приспособления

Django будет искать светильники в следующих местах:

  1. В каталоге fixtures каждого установленного приложения.

  2. В любом каталоге, указанном в настройке FIXTURE_DIRS.

  3. В буквальном пути, указанном в приспособлении

Django загрузит все фикстуры, которые он найдет в этих местах и ​​которые соответствуют указанным именам фикстур. Если указанный прибор имеет расширение файла, будут загружены только приборы этого типа. Например:

django-admin loaddata mydata.json

будет загружать только JSON-фикстуры, называемые mydata. Расширение фикстуры должно соответствовать зарегистрированному имени сериализатора <serialization-formats> (например, json или xml).

Если вы опустите расширения, Django выполнит поиск подходящего прибора во всех доступных типах приборов. Например:

django-admin loaddata mydata

будет искать любое устройство любого типа, называемое mydata. Если каталог фикстур содержит mydata.json, эта фикстура будет загружена как фикстура JSON.

Именованные приборы могут включать в себя компоненты каталога. Эти каталоги будут включены в путь поиска. Например:

django-admin loaddata foo/bar/mydata.json

будет искать <app_label>/fixtures/foo/bar/mydata.json для каждого установленного приложения, <dirname>/foo/bar/mydata.json для каждого каталога в FIXTURE_DIRS и буквальный путь foo/bar/mydata.json.

Порядок загрузки светильников

В одном вызове можно указать несколько фикстур. Например:

django-admin loaddata mammals birds insects

или в классе тестового примера:

class AnimalTestCase(TestCase):
    fixtures = ["mammals", "birds", "insects"]

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

В этих примерах сначала будут загружены все устройства с именем «млекопитающие» из всех приложений (в том порядке, в котором приложения определены в INSTALLED_APPS). Впоследствии будут загружены все приборы birds, а затем все приборы insects.

Имейте в виду, что если серверная часть базы данных поддерживает ограничения на уровне строк, эти ограничения будут проверены в конце транзакции. Любые отношения между фикстурами могут привести к ошибке загрузки, если конфигурация базы данных не поддерживает отложенную проверку ограничений (пример см. в документации MySQL).

Как светильники сохраняются в базе данных

При обработке файлов приборов данные сохраняются в базе данных как есть. Определенные в модели методы save() не вызываются, и любые сигналы pre_save или post_save будут вызываться с raw=True, поскольку экземпляр содержит только локальные для модели атрибуты. Например, вы можете захотеть отключить обработчики, которые обращаются к связанным полям, которые отсутствуют во время загрузки прибора и в противном случае вызвали бы исключение:

from django.db.models.signals import post_save
from .models import MyModel


def my_handler(**kwargs):
    # disable the handler during fixture loading
    if kwargs["raw"]:
        return
    ...


post_save.connect(my_handler, sender=MyModel)

Вы также можете написать декоратор для инкапсуляции этой логики:

from functools import wraps


def disable_for_loaddata(signal_handler):
    """
    Decorator that turns off signal handlers when loading fixture data.
    """

    @wraps(signal_handler)
    def wrapper(*args, **kwargs):
        if kwargs["raw"]:
            return
        signal_handler(*args, **kwargs)

    return wrapper


@disable_for_loaddata
def my_handler(**kwargs): ...

Просто имейте в виду, что эта логика отключит сигналы всякий раз, когда фикстуры десериализуются, а не только во время loaddata.

Сжатые светильники

Fixtures may be compressed in zip, gz, bz2, lzma, or xz format. Например:

django-admin loaddata mydata.json

будет искать любой из mydata.json, mydata.json.zip, mydata.json.gz, mydata.json.bz2, mydata.json.lzma или mydata.json.xz. Используется первый файл, содержащийся в сжатом архиве.

Обратите внимание: если будут обнаружены два фикстуры с одинаковым именем, но с разными типами фикстур (например, если mydata.json и mydata.xml.gz были найдены в одном и том же каталоге фикстур), установка фикстур будет прервана, а любые данные, установленные при вызове loaddata, будут удалены из базы данных.

MySQL с MyISAM и фикстурами

Механизм хранения MyISAM в MySQL не поддерживает транзакции или ограничения, поэтому, если вы используете MyISAM, вы не получите проверки данных фиксации или отката, если обнаружено несколько файлов транзакций.

Фикстуры, специфичные для базы данных

Если вы используете установку с несколькими базами данных, у вас могут быть данные о приборах, которые вы хотите загрузить в одну базу данных, но не в другую. В этой ситуации вы можете добавить идентификатор базы данных в имена ваших приборов.

Например, если в вашем параметре DATABASES определена база данных users, назовите это приспособление mydata.users.json или mydata.users.json.gz, и оно будет загружено только тогда, когда вы укажете, что хотите загрузить данные в базу данных users.

Back to Top