62 votes

Modification des tables de base de données dans Django

J'envisage d'utiliser Django pour un projet que je démarre (pour info, un jeu basé sur un navigateur) et l'une des fonctionnalités que j'apprécie le plus est l'utilisation de la fonction syncdb pour créer automatiquement les tables de la base de données en fonction des modèles Django que je définis (une fonctionnalité que je n'arrive à trouver dans aucun autre framework). Je me disais déjà que c'était trop beau pour être vrai quand j'ai vu ceci dans la section documentation :

Syncdb ne modifiera pas les tables existantes

syncdb ne créera des tables que pour les modèles qui n'ont pas encore été installés. Il n'émettra jamais d'instructions ALTER TABLE pour correspondre aux modifications apportées à une classe de modèle après l'installation. Les modifications apportées aux classes de modèles et aux schémas de bases de données impliquent souvent une certaine forme d'ambiguïté et, dans ces cas, Django doit deviner les modifications correctes à apporter. Il y a un risque que des données critiques soient perdues dans le processus.

Si vous avez apporté des modifications à un modèle et que vous souhaitez modifier les tables de la base de données pour qu'elles correspondent, utilisez la commande sql pour afficher la nouvelle structure SQL et la comparer à votre schéma de table existant pour effectuer les modifications.

Il semble que la modification des tableaux existants doive être effectuée "à la main".

Ce que je voudrais savoir, c'est la meilleure façon de procéder. Deux solutions me viennent à l'esprit :

  • Comme le suggère la documentation, effectuez les changements manuellement dans la BD ;
  • Faire une sauvegarde de la base de données, l'effacer, créer à nouveau les tables (avec syncdb, puisque maintenant il crée les tables à partir de zéro) et importer les données sauvegardées (cela peut prendre trop de temps si la base de données est grande).

Des idées ?

61voto

Carl Meyer Points 30736

Effectuer manuellement les modifications SQL et le dump/reload sont deux options, mais vous pouvez également consulter certains des paquets d'évolution des schémas pour Django. Les options les plus abouties sont django-évolution y Sud .

EDIT : Et hé, voici dmigrations .

UPDATE : Depuis que cette réponse a été écrite à l'origine, django-évolution y dmigrations ont tous deux cessé leur développement actif et Sud est devenu la norme de facto pour la migration des schémas dans Django. Certaines parties de South pourraient même être intégrées à Django dans la prochaine ou les deux prochaines versions.

UPDATE : Un cadre de migration de schémas basé sur South (et rédigé par Andrew Godwin, auteur de South) est inclus dans Django 1.7+.

1 votes

Django-evolution a semblé bien fonctionner, merci ! Il est important de noter que l'on doit commencer à l'utiliser dès le début (il ne calcule pas les changements nécessaires à partir de SQL existant).

17voto

akaihola Points 10007

Comme indiqué dans d'autres réponses au même sujet, assurez-vous de regarder les Panel sur l'évolution des schémas de la DjangoCon 2008 sur YouTube.

Aussi, deux nouveaux projets sur la carte : Simplemigrations y Migrateurs .

9voto

Dave Webb Points 90034

Un bon moyen d'y parvenir est d'utiliser les fixtures, en particulier la fonction initial_data des appareils.

Un fixture est une collection de fichiers qui contiennent le contenu sérialisé de la base de données. C'est donc comme avoir une sauvegarde de la base de données, mais comme Django en est conscient, c'est plus facile à utiliser et cela présente des avantages supplémentaires lorsque vous faites des choses comme les tests unitaires.

Vous pouvez créer un dispositif à partir des données actuellement présentes dans votre base de données en utilisant django-admin.py dumpdata . Par défaut, les données sont au format JSON, mais d'autres options telles que XML sont disponibles. Un bon endroit pour stocker les fixtures est un fixtures dans le sous-répertoire de vos répertoires d'application.

Vous pouvez charger une fixation en utilisant django-admin.py loaddata mais plus important encore, si votre appareil a un nom tel que initial_data.json il sera automatiquement chargé lorsque vous ferez une syncdb ce qui vous évite d'avoir à l'importer vous-même.

Un autre avantage est que lorsque vous exécutez manage.py test pour exécuter vos tests unitaires, la base de données de test temporaire aura également le Data Fixture initial chargé.

Bien entendu, cela fonctionne lorsque vous ajoutez des attributs aux modèles et des colonnes à la base de données. Si vous supprimez une colonne de la base de données, vous devrez mettre à jour votre dispositif pour supprimer les données de cette colonne, ce qui n'est pas toujours simple.

Cette méthode est la plus efficace lorsque vous effectuez un grand nombre de petites modifications de la base de données pendant le développement. Pour la mise à jour des bases de données de production, un script SQL généré manuellement est souvent plus efficace.

4voto

Garth Kidd Points 2792

J'ai utilisé django-evolution. Les mises en garde sont les suivantes :

  • Ses suggestions automatiques ont été uniformément pourries ; et
  • Sa fonction d'empreinte digitale renvoie des valeurs différentes pour la même base de données sur différentes plateformes.

Cela dit, je trouve que la coutume schema_evolution.py approche pratique. Pour contourner le problème de l'empreinte digitale, je suggère un code comme :

BEFORE = 'fv1:-436177719' # first fingerprint
BEFORE64 = 'fv1:-108578349625146375' # same, but on 64-bit Linux
AFTER = 'fv1:-2132605944' 
AFTER64 = 'fv1:-3559032165562222486'

fingerprints = [
    BEFORE, AFTER,
    BEFORE64, AFTER64,
    ]

CHANGESQL = """
    /* put your SQL code to make the changes here */
    """

evolutions = [
    ((BEFORE, AFTER), CHANGESQL),
    ((BEFORE64, AFTER64), CHANGESQL)
    ]

Si j'avais plus d'empreintes et de changements, je le remanierais. En attendant, le rendre plus propre serait une perte de temps de développement pour autre chose.

EDITAR: Étant donné que je construis manuellement mes changements de toute façon, je vais essayer dmigrations la prochaine fois.

0 votes

Pour les évolutions simples comme l'ajout, la suppression ou le renommage de champs, django-evolution a bien fonctionné pour moi. Parfois, je dois ajouter une valeur par défaut que je préférerais ne pas spécifier dans le modèle (et plutôt dire à django-evolution de juste la définir pour les champs existants) mais à part cela - pas de plaintes.

3voto

defrex Points 2448

django-command-extensions est une bibliothèque django qui donne quelques commandes supplémentaires à manage.py. L'une d'entre elles est sqldiff, qui devrait vous fournir le code SQL nécessaire à la mise à jour de votre nouveau modèle. Elle est cependant listée comme 'très expérimentale'.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X