Comment gérer efficacement les changements de schéma fréquents en utilisant sqlalchemy?
Je programme une application web en utilisant sqlalchemy. Tout s'est déroulé en douceur lors de la première phase de développement alors que le site n'était pas en production. Je pourrais facilement changer le schéma de base de données en supprimant simplement l'ancienne base de données sqlite et en créant une nouvelle à partir de zéro.
maintenant le site est en production et j'ai besoin de préserver les données, mais je veux toujours garder ma vitesse de développement originale en convertissant facilement la base de données au nouveau schéma.
alors disons que j'ai model.py lors de la révision 50 et model.py une révision 75, décrivant le schéma de la base de données. Entre ces deux schémas, la plupart des modifications sont triviales, par exemple une nouvelle colonne est déclarée avec une valeur par défaut et je veux juste ajouter cette valeur par défaut aux anciens enregistrements.
éventuellement quelques changements peuvent ne pas être triviaux et nécessitent un certain pré-calcul.
Comment faites-vous (ou feriez-vous) pour gérer les applications Web en évolution rapide avec, une ou deux nouvelles versions du code de production par jour ?
Par ailleurs, le site est écrit en Pylônes si cela fait une différence.
4 réponses
Alembic est un nouvel outil de migration de base de données, écrit par L'auteur de SQLAlchemy. Je l'ai trouvé beaucoup plus facile à utiliser que sqlalchemy-migrer. Il fonctionne également parfaitement avec Flask-SQLAlchemy.
générer automatiquement le script de migration schema à partir de vos modèles SQLAlchemy:
alembic revision --autogenerate -m "description of changes"
puis appliquer les nouveaux changements de schéma à votre base de données:
alembic upgrade head
plus d'informations ici: http://readthedocs.org/docs/alembic /
ce que nous faisons.
-
Utiliser "version majeure"."version mineure" identification de vos applications. La version principale est le numéro de version du schéma. Le numéro principal n'est pas une sorte de "suffisamment de nouvelles fonctionnalités" au hasard. C'est une déclaration formelle de compatibilité avec le schéma de la base de données.
version 2.3 et 2.4 utilisent la version 2 de schema.
Version 3.1 utilise le schéma de la version 3.
-
rendent la version schema très, très visible. Pour SQLite, cela signifie Garder le numéro de version du schéma dans le nom de fichier de la base de données. Pour MySQL, utilisez le nom de la base de données.
-
Écrire des scripts de migration. 2to3.py, 3to4.py. Ces scripts fonctionnent en deux phases. (1) interrogez les anciennes données dans la nouvelle structure en créant des fichiers CSV ou JSON simples. (2) Chargez la nouvelle structure à partir des fichiers CSV ou JSON simples sans plus traitement. Ces fichiers d'extraction -- parce qu'ils sont dans la bonne structure, sont rapides à charger et peuvent facilement être utilisés comme des fixtures de test d'unité. Aussi, vous n'avez jamais deux bases de données ouvertes en même temps. Cela rend les scripts légèrement plus simples. Enfin, le chargement de fichiers peuvent être utilisés pour déplacer les données vers un autre serveur de base de données.
il est très, très difficile d '"automatiser" la migration des schémas. Il est facile (et commun) d'avoir la chirurgie de base de données si profonde que le script automatisé ne peut pas facilement mapper les données de l'ancien schéma à un nouveau schéma.
Utiliser sqlalchemy-migrer .
il est conçu pour soutenir une approche agile à la conception de base de données, et il est plus facile de garder les bases de données de développement et de production dans la synchronisation, comme les changements de schéma sont nécessaires. Il rend schema versioning facile.
pensez - y comme un contrôle de version pour votre schéma de base de données. Vous commettez chaque changement de schéma, et il sera capable d'aller de l'avant/en arrière sur les versions de schéma. De cette façon, vous peut mettre à niveau un client et il saura exactement quel ensemble de changements appliquer sur la base de données de ce client.
il fait ce que S. Lott propose dans sa réponse, automatiquement pour vous. Fait une chose difficile facile.
la meilleure façon de traiter votre problème est de refléter votre schéma plutôt que de le faire de manière déclarative. J'ai écrit un article sur l'approche réfléchie ici.: http://petrushev.wordpress.com/2010/06/16/reflective-approach-on-sqlalchemy-usage / mais il y a d'autres ressources à propos de cette également. De cette façon, chaque fois que vous apportez des modifications à votre schéma, tout ce que vous avez à faire est de redémarrer l'application et la réflexion récupérera les nouvelles métadonnées pour les modifications table. C'est assez rapide et sqlalchemy ne le fait qu'une fois par processus. Bien sûr, tu devras gérer les changements de relations que tu feras toi-même.