forked from django/django
-
Notifications
You must be signed in to change notification settings - Fork 0
/
fixtures.txt
171 lines (118 loc) · 5.58 KB
/
fixtures.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
.. _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>`.
Where 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:
.. code-block:: shell
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:
.. code-block:: shell
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:
.. code-block:: shell
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:
.. code-block:: shell
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.