InstantanésLien vers cette rubrique
Un instantané est un ensemble de fichiers contenant du contenu sérialisé de base de données. Chaque instantané possède un nom unique et les fichiers composant l’instantané peuvent être distribués dans plusieurs répertoires et plusieurs applications.
Comment produire un instantanéLien vers cette rubrique
Les instantanés peuvent être générés par la commande manage.py dumpdata. Il est aussi possible de produire des instantanés personnalisés en utilisant directement les outils de sérialisation ou même en les écrivant à la main.
Comment utiliser un instantanéLien vers cette rubrique
Les instantanés peuvent être utilisés pour préremplir la base de données avec des données pour les tests:
class MyTestCase(TestCase):
fixtures = ["fixture-label"]
ou pour fournir des données initiales en utilisant la commande loaddata:
django-admin loaddata <fixture label>
Découvrabilité des instantanésLien vers cette rubrique
Django recherche les instantanés à ces emplacements :
Dans le répertoire
fixturesde chaque application installéeDans tout répertoire mentionné dans le réglage
FIXTURE_DIRSDans le chemin explicitement contenu dans le nom de l’instantané
Django va charger tous les instantanés qu’il trouve aux emplacements indiqués par les noms d’instantanés. Si un nom d’instantané indiqué possède une extension de fichier, seuls des instantanés de ce type seront chargés. Par exemple :
django-admin loaddata mydata.json
ne charge que les instantanés JSON nommés mydata. L’extension d’instantané doit correspondre au nom enregistré d’un sérialiseur (par ex. json ou xml).
Si vous omettez l’extension, Django recherche tous les types d’instantané disponibles pour chaque instantané trouvé. Par exemple :
django-admin loaddata mydata
recherche tout instantané ou type d’instantané nommé mydata. Si un répertoire d’instantané contient mydata.json, cet instantané serait chargé comme instantané JSON.
Les noms d’instantanés peuvent contenir une partie « chemin ». Ces répertoires sont alors inclus dans le chemin de recherche. Par exemple :
django-admin loaddata foo/bar/mydata.json
recherche <étiquette_app>/fixtures/foo/bar/mydata.json pour chaque application installée, <nom_rép>/foo/bar/mydata.json pour chaque répertoire dans FIXTURE_DIRS ainsi que le chemin littéral foo/bar/mydata.json.
Ordre de chargement des instantanésLien vers cette rubrique
Plusieurs instantanés peuvent être indiqués dans la même invocation. Par exemple :
django-admin loaddata mammals birds insects
ou dans une classe de cas de tests :
class AnimalTestCase(TestCase):
fixtures = ["mammals", "birds", "insects"]
L’ordre dans lequel sont chargés les instantanés suit l’ordre dans lequel ils sont indiqués, que ce soit lors de l’utilisation de la commande d’administration ou quand ils sont mentionnés dans une classe de cas de tests comme démontré plus haut.
Dans ces exemples, tous les instantanés nommés mammals dans toutes les applications (dans l’ordre d’apparition des applications dans INSTALLED_APPS) seront chargés en premier. Puis, tous les instantanés birds seront chargés, suivis par tous les instantanés insects.
Sachez que si le moteur de base de données gère les contraintes de lignes, celles-ci seront vérifiées à la fin de la transaction. Toute relation traversant les instantanés peut aboutir à une erreur de chargement si la configuration de base de données ne prend pas en charge le contrôle différé des contraintes (référez-vous à la documentation de MySQL pour un exemple).
Comment les instantanés sont enregistrés en base de donnéesLien vers cette rubrique
When fixture files are processed, the data is saved to the database as is.
Model defined save() methods are not called, and
any pre_save,
post_save, or
m2m_changed 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)
On pourrait aussi écrire un décorateur pour encapsuler cette logique :
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): ...
Il faut cependant être conscient que cette logique désactivera les signaux lors de chaque désérialisation des instantanés, pas seulement durant loaddata.
Instantanés compressésLien vers cette rubrique
Les instantanés peuvent être compressés dans les formats zip, gz, bz2, lzma ou xz. Par exemple :
django-admin loaddata mydata.json
recherche l’un des fichiers mydata.json, mydata.json.zip, mydata.json.gz, mydata.json.bz2, mydata.json.lzma ou mydata.json.xz. Le premier fichier contenu dans une archive compressée est utilisé.
Notez que si deux instantanés de même nom mais de type différent sont trouvés (par exemple si mydata.json et mydata.xml.gz sont trouvés dans le même répertoire d’instantanés), l’installation des instantanés est interrompue et toute donnée déjà installée par l’appel à loaddata est retirée de la base de données.
Instantanés spécifiques à certaines bases de donnéesLien vers cette rubrique
Si vous vous trouvez dans une configuration avec plusieurs bases de données, il se pourrait que vous vouliez charger certains instantanés dans une base de données mais pas dans l’autre. Dans cette situation, vous pouvez insérer des identifiants de base de données dans les noms des instantanés.
Par exemple, si votre réglage DATABASES contient une base de données users, nommez l’instantané mesdonnees.users.json ou mesdonnees.users.json.gz et cet instantané ne sera chargé que lorsque vous indiquez que vous souhaitez charger des données dans la base de données users.