Modification des tables de la base de données à Django

J'envisage D'utiliser Django pour un projet que je lance (fyi, un jeu basé sur un navigateur) et l'une des fonctionnalités que j'aime le plus est d'utiliser syncdb pour créer automatiquement les tables de base de données basées sur les modèles Django que je définis (une fonctionnalité que je ne semble pas trouver dans un autre cadre). Je pensais déjà que c'était trop beau pour être vrai quand j'ai vu cela dans la documentation :

Syncdb ne modifiera pas tableaux

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 faire correspondre les modifications apportées à une classe de modèle après l'installation. Les modifications des classes de modèles et des schémas de bases de données impliquent souvent une certaine ambiguïté et, dans ces cas, Django devrait deviner les changements à apporter. Il y a un risque que des données critiques soient perdues au cours du processus.

Si vous avez fait modifications à un modèle et souhaitez modifier les tables de base de données pour correspondre, utilisez la commande sql pour afficher la nouvelle structure SQL et comparez cela à votre schéma de table existant pour travailler sur les changements.

il semble que la modification des tables existantes devra être faite"à la main".

ce que je voudrais savoir est la meilleure façon de le faire. Deux solutions viennent à l'esprit:

  • comme le suggère la documentation, faire le change manuellement dans le DB;
  • faites une sauvegarde de la base de données, essuyez-la, créez à nouveau les tables (avec syncdb, depuis maintenant il crée les tables à partir de zéro) et importer les données sauvegardées (cela pourrait prendre trop de temps si la base de données est grande)

des idées?

59
demandé sur dfarrell07 2008-08-30 18:36:39

8 réponses

comme indiqué dans d'autres réponses au même sujet, assurez-vous de regarder le DjangoCon 2008 Schema Evolution Panel sur YouTube.

également, deux nouveaux projets sur la carte: migrations simples et migration .

16
répondu akaihola 2009-01-16 12:10:20

faire manuellement les changements SQL et dump/reload sont les deux options, mais vous pouvez également consulter certains des paquets schema-evolution pour Django. Les options les plus mûres sont django-evolution et Sud .

MODIFIER : Et hey, voici dmigrations .

mise à jour : depuis cette réponse a été écrite à l'origine, django-évolution et dmigrations ont tous deux cessé sa participation active au développement et à la Sud est devenu le standard de facto pour le schéma de migration dans Django. Certaines parties du Sud peuvent même être intégrées dans Django dans la prochaine version ou les deux suivantes.

mise à JOUR : UN schéma des migrations cadre de travail basé sur le Sud (et rédigé par Andrew Godwin, auteur du Sud) est inclus dans Django 1.7+.

59
répondu Carl Meyer 2015-07-31 13:11:25

une bonne façon de le faire est via fixtures, en particulier les fixtures initial_data .

une fixture est un ensemble de fichiers qui contiennent le contenu sérialisé de la base de données. Donc C'est comme avoir une sauvegarde de la base de données, mais comme C'est quelque chose que Django est conscient que C'est plus facile à utiliser et aura des avantages supplémentaires quand vous venez pour faire des choses comme le test de l'unité.

vous pouvez créer un montage à partir des données actuellement 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 des fixtures est un fixtures sous-répertoire de vos répertoires d'application.

vous pouvez charger une fixure en utilisant django-admin.py loaddata mais plus important, si votre fixture a un nom comme initial_data.json il sera automatiquement chargé lorsque vous faites un syncdb , économisant la peine de l'importer vous-même.

un autre avantage est que lorsque vous lancez manage.py test pour exécuter les Tests de votre unité la base de données des tests temporaires sera également chargée.

bien sûr, cela fonctionnera lorsque vous ajoutez des attributs à des modèles et des colonnes à la base de données. Si vous supprimez une colonne de la base de données, vous aurez besoin de mettre à jour votre fixture pour supprimer les données de cette colonne qui pourrait ne pas être simple.

cela fonctionne mieux quand on fait beaucoup de petits changements de base de données pendant le développement. Pour mise à jour de la production DBs un script SQL généré manuellement peut souvent mieux fonctionner.

9
répondu Dave Webb 2008-08-30 19:28:44

j'ai utilisé django-evolution. Les mises en garde comprennent:

  • ses suggestions automatiques ont été uniformément pourrie; et
  • sa fonction fingerprint renvoie des valeurs différentes pour la même base de données sur des plateformes différentes.

cela dit, je trouve l'approche personnalisée schema_evolution.py pratique. Pour contourner le problème des empreintes digitales, 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 corrigerais. D'ici là, le rendre plus propre serait voler du temps de développement à autre chose.

EDIT: étant Donné que je suis manuellement la construction de mes changements de toute façon, je vais essayer dmigrations la prochaine fois.

4
répondu Garth Kidd 2008-09-11 02:44:47

django-command-extensions est une bibliothèque django qui donne quelques commandes supplémentaires à manage.py. L'un d'eux est sqldiff, qui devrait vous donner le sql nécessaire pour mettre à jour votre nouveau modèle. Elle est cependant qualifiée de "très expérimentale".

3
répondu defrex 2008-09-11 23:33:07

jusqu'à présent, dans mon entreprise nous avons utilisé l'approche manuelle. Ce qui fonctionne le mieux pour vous dépend beaucoup de votre style de développement.

nous n'avons généralement pas tellement de changements de schéma dans les systèmes de production et de déploiements quelque peu formalisés du développement aux serveurs de production. Chaque fois que nous déployons (10-20 fois par an) nous faisons une différence de remplissage de la branche de production actuelle et à venir en passant en revue tout le code et en notant ce qui doit être changé sur le serveur de production. Les modifications nécessaires peuvent être des dépendances supplémentaires, des modifications au fichier de paramètres et des modifications à la base de données.

Cela fonctionne très bien pour nous. Avoir tout automatisé est une vision de niche mais difficile pour nous - peut-être que nous pourrions gérer les migrations, mais nous aurions encore besoin de gérer une bibliothèque supplémentaire, serveur, quelles que soient les dépendances.

2
répondu max 2009-01-04 14:26:54

Le Livre de Django explique comment le faire à la main.

http://www.djangobook.com/en/2.0/chapter10 /

Je l'ai fait plusieurs fois de cette façon, et il est très flexible, vous permettant de laisser des données dans les tableaux tout en les retirant du modèle.

j'ai commencé à utiliser le Sud récemment. Il semble un peu moins souple (ou peut-être que j'ai juste besoin de lire la documentation un peu plus.) Mais peut vous sauver un peu de taper. Parfois, on arrive à le désynchroniser avec la base de données, ce qui est un cauchemar. Ça a l'air de bien se passer tant que tu l'utilises.Il ne semble pas lier les modèles et la base de données réelle ensemble, ce qui peut ou ne pas être une bonne chose selon votre situation

2
répondu wobbily_col 2012-06-13 08:24:52

Django 1.7 (actuellement en développement) est ajout d'un support natif pour la migration schématique avec manage.py migrate et manage.py makemigrations ( migrate déprécie syncdb ).

2
répondu Jan Wrobel 2013-12-17 17:23:14