mirror of
https://github.com/django/django.git
synced 2025-10-24 06:06:09 +00:00
Fixed #34054 -- Created a new fixtures topic.
Moved material from django-admin document into a new document, and added new material. Co-authored-by: Mariusz Felisiak <felisiak.mariusz@gmail.com>
This commit is contained in:
committed by
Mariusz Felisiak
parent
c765b62e32
commit
6103059592
157
docs/topics/db/fixtures.txt
Normal file
157
docs/topics/db/fixtures.txt
Normal file
@@ -0,0 +1,157 @@
|
||||
.. _fixtures-explanation:
|
||||
|
||||
========
|
||||
Fixtures
|
||||
========
|
||||
|
||||
.. seealso::
|
||||
|
||||
* :doc:`/howto/initial-data`
|
||||
|
||||
What is a fixture?
|
||||
==================
|
||||
|
||||
A *fixture* is a collection of files that contain the serialized contents of
|
||||
the database. Each fixture has a unique name, and the files that comprise the
|
||||
fixture can be distributed over multiple directories, in multiple applications.
|
||||
|
||||
How to produce a fixture?
|
||||
=========================
|
||||
|
||||
Fixtures can be generated by :djadmin:`manage.py dumpdata <dumpdata>`. It's
|
||||
also possible to generate custom fixtures by directly using
|
||||
:doc:`serialization documentation </topics/serialization>` tools or even by
|
||||
handwriting them.
|
||||
|
||||
What to use a fixture for?
|
||||
==========================
|
||||
|
||||
Fixtures can be used to pre-populate database with data for
|
||||
:ref:`tests <topics-testing-fixtures>` or to provide some :ref:`initial data
|
||||
<initial-data-via-fixtures>`.
|
||||
|
||||
Were Django looks for fixtures?
|
||||
===============================
|
||||
|
||||
Django will search in three locations for fixtures:
|
||||
|
||||
1. In the ``fixtures`` directory of every installed application
|
||||
2. In any directory named in the :setting:`FIXTURE_DIRS` setting
|
||||
3. In the literal path named by the fixture
|
||||
|
||||
Django will load any and all fixtures it finds in these locations that match
|
||||
the provided fixture names.
|
||||
|
||||
If the named fixture has a file extension, only fixtures of that type
|
||||
will be loaded. For example::
|
||||
|
||||
django-admin loaddata mydata.json
|
||||
|
||||
would only load JSON fixtures called ``mydata``. The fixture extension
|
||||
must correspond to the registered name of a
|
||||
:ref:`serializer <serialization-formats>` (e.g., ``json`` or ``xml``).
|
||||
|
||||
If you omit the extensions, Django will search all available fixture types
|
||||
for a matching fixture. For example::
|
||||
|
||||
django-admin loaddata mydata
|
||||
|
||||
would look for any fixture of any fixture type called ``mydata``. If a fixture
|
||||
directory contained ``mydata.json``, that fixture would be loaded
|
||||
as a JSON fixture.
|
||||
|
||||
The fixtures that are named can include directory components. These
|
||||
directories will be included in the search path. For example::
|
||||
|
||||
django-admin loaddata foo/bar/mydata.json
|
||||
|
||||
would search ``<app_label>/fixtures/foo/bar/mydata.json`` for each installed
|
||||
application, ``<dirname>/foo/bar/mydata.json`` for each directory in
|
||||
:setting:`FIXTURE_DIRS`, and the literal path ``foo/bar/mydata.json``.
|
||||
|
||||
How fixtures are saved to the database?
|
||||
=======================================
|
||||
|
||||
When fixture files are processed, the data is saved to the database as is.
|
||||
Model defined :meth:`~django.db.models.Model.save` methods are not called, and
|
||||
any :data:`~django.db.models.signals.pre_save` or
|
||||
:data:`~django.db.models.signals.post_save` signals will be called with
|
||||
``raw=True`` since the instance only contains attributes that are local to the
|
||||
model. You may, for example, want to disable handlers that access
|
||||
related fields that aren't present during fixture loading and would otherwise
|
||||
raise an exception::
|
||||
|
||||
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)
|
||||
|
||||
You could also write a decorator to encapsulate this logic::
|
||||
|
||||
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):
|
||||
...
|
||||
|
||||
Just be aware that this logic will disable the signals whenever fixtures are
|
||||
deserialized, not just during ``loaddata``.
|
||||
|
||||
Note that the order in which fixture files are processed is undefined. However,
|
||||
all fixture data is installed as a single transaction, so data in
|
||||
one fixture can reference data in another fixture. If the database backend
|
||||
supports row-level constraints, these constraints will be checked at the
|
||||
end of the transaction.
|
||||
|
||||
Compressed fixtures
|
||||
===================
|
||||
|
||||
Fixtures may be compressed in ``zip``, ``gz``, ``bz2``, ``lzma``, or ``xz``
|
||||
format. For example::
|
||||
|
||||
django-admin loaddata mydata.json
|
||||
|
||||
would look for any of ``mydata.json``, ``mydata.json.zip``, ``mydata.json.gz``,
|
||||
``mydata.json.bz2``, ``mydata.json.lzma``, or ``mydata.json.xz``. The first
|
||||
file contained within a compressed archive is used.
|
||||
|
||||
Note that if two fixtures with the same name but different
|
||||
fixture type are discovered (for example, if ``mydata.json`` and
|
||||
``mydata.xml.gz`` were found in the same fixture directory), fixture
|
||||
installation will be aborted, and any data installed in the call to
|
||||
``loaddata`` will be removed from the database.
|
||||
|
||||
.. admonition:: MySQL with MyISAM and fixtures
|
||||
|
||||
The MyISAM storage engine of MySQL doesn't support transactions or
|
||||
constraints, so if you use MyISAM, you won't get validation of fixture
|
||||
data, or a rollback if multiple transaction files are found.
|
||||
|
||||
Database-specific fixtures
|
||||
==========================
|
||||
|
||||
If you're in a multi-database setup, you might have fixture data that
|
||||
you want to load onto one database, but not onto another. In this
|
||||
situation, you can add a database identifier into the names of your fixtures.
|
||||
|
||||
For example, if your :setting:`DATABASES` setting has a ``users`` database
|
||||
defined, name the fixture ``mydata.users.json`` or
|
||||
``mydata.users.json.gz`` and the fixture will only be loaded when you
|
||||
specify you want to load data into the ``users`` database.
|
||||
@@ -22,4 +22,5 @@ Generally, each model maps to a single database table.
|
||||
tablespaces
|
||||
optimization
|
||||
instrumentation
|
||||
fixtures
|
||||
examples/index
|
||||
|
||||
@@ -1101,7 +1101,7 @@ Fixture loading
|
||||
A test case for a database-backed website isn't much use if there isn't any
|
||||
data in the database. Tests are more readable and it's more maintainable to
|
||||
create objects using the ORM, for example in :meth:`TestCase.setUpTestData`,
|
||||
however, you can also use fixtures.
|
||||
however, you can also use :ref:`fixtures <fixtures-explanation>`.
|
||||
|
||||
A fixture is a collection of data that Django knows how to import into a
|
||||
database. For example, if your site has user accounts, you might set up a
|
||||
@@ -1139,8 +1139,8 @@ Here's specifically what will happen:
|
||||
|
||||
* Then, all the named fixtures are installed. In this example, Django will
|
||||
install any JSON fixture named ``mammals``, followed by any fixture named
|
||||
``birds``. See the :djadmin:`loaddata` documentation for more
|
||||
details on defining and installing fixtures.
|
||||
``birds``. See the :ref:`fixtures-explanation` topic for more details on
|
||||
defining and installing fixtures.
|
||||
|
||||
For performance reasons, :class:`TestCase` loads fixtures once for the entire
|
||||
test class, before :meth:`~TestCase.setUpTestData`, instead of before each
|
||||
|
||||
Reference in New Issue
Block a user