Avec la nouvelle fonctionnalité multi-db de Django dans la version de développement, j'ai essayé de travailler sur la création d'une commande de gestion qui me permet de synchroniser les données du site en direct vers une machine de développement pour des tests étendus. (Avoir des données réelles, en particulier celles saisies par l'utilisateur, me permet de tester un plus large éventail d'entrées.)
Actuellement, j'ai une commande "presque" fonctionnelle. Elle peut synchroniser les données des modèles "simples", mais le problème que j'ai est qu'elle ignore les champs ManyToMany pour lesquels je ne vois aucune raison. Quelqu'un a des idées sur la manière de résoudre cela ou une meilleure façon de gérer cela? Devrais-je exporter cette première requête vers une fixture d'abord puis la réimporter?
from django.core.management.base import LabelCommand
from django.db.utils import IntegrityError
from django.db import models
from django.conf import settings
LIVE_DATABASE_KEY = 'live'
class Command(LabelCommand):
help = ("Synchronise les données entre la machine locale et le serveur en direct")
args = "NOM_DE_L'APPLICATION"
label = 'nom de l'application'
requires_model_validation = False
can_import_settings = True
def handle_label(self, label, **options):
# Assurons que la commande s'exécute sur une machine de développement et que les paramètres sont corrects
db_settings = getattr(settings, 'DATABASES', {})
if not LIVE_DATABASE_KEY in db_settings:
print 'Impossible de trouver "%s" dans les paramètres de la base de données.' % LIVE_DATABASE_KEY
return
if db_settings.get('default') == db_settings.get(LIVE_DATABASE_KEY):
print 'Les données ne peuvent pas se synchroniser avec elles-mêmes. Cette commande doit être exécutée sur un serveur non-productif.'
return
# Récupérer tous les modèles pour l'application donnée
try:
app = models.get_app(label)
app_models = models.get_models(app)
except:
print "L'application '%s' n'a pas pu être trouvée ou les modèles n'ont pas pu être chargés pour celle-ci." % label
for model in app_models:
print 'Synchronisation de %s.%s ...' % (model._meta.app_label, model._meta.object_name)
# Interroger chaque modèle du site en direct
qs = model.objects.all().using(LIVE_DATABASE_KEY)
# ...et le sauvegarder dans la base de données locale
for enregistrement in qs:
try:
enregistrement.save(using='default')
except IntegrityError:
# Ignorer car l'enregistrement existe probablement déjà
pass