web-dev-qa-db-fra.com

Comment gérer efficacement les changements de schéma fréquents à l'aide de sqlalchemy?

Je programme une application web en utilisant sqlalchemy. Tout s'est bien passé lors de la première phase de développement lorsque le site n'était pas en production. Je pouvais facilement changer le schéma de la 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 je dois conserver les données, mais je veux toujours conserver ma vitesse de développement d'origine en convertissant facilement la base de données vers le nouveau schéma.

Disons donc que j'ai model.py à 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.

Finalement, quelques modifications peuvent ne pas être triviales et nécessitent un certain calcul préalable.

Comment gérez-vous (ou feriez-vous) les applications Web à évolution rapide avec, par exemple, une ou deux nouvelles versions du code de production par jour?

Soit dit en passant, le site est écrit en pylônes si cela fait une différence.

52
ascobol

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-migrate. Il fonctionne également de manière transparente avec Flask-SQLAlchemy.

Générez automatiquement le script de migration de schéma à partir de vos modèles SQLAlchemy:

alembic revision --autogenerate -m "description of changes"

Appliquez ensuite les nouvelles modifications de schéma à votre base de données:

alembic upgrade head

Plus d'informations ici: http://readthedocs.org/docs/alembic/

36
Alan Hamlett

Ce que nous faisons.

  1. Utilisez l'identification "version majeure". "Version mineure" de vos applications. La version principale est le numéro de version du schéma. Le plus grand nombre n'est pas quelque chose de aléatoire "assez de nouvelles fonctionnalités". Il s'agit d'une déclaration officielle de compatibilité avec le schéma de base de données.

    Les versions 2.3 et 2.4 utilisent toutes deux la version 2 du schéma.

    La version 3.1 utilise le schéma de la version 3.

  2. Rendez la version du schéma très, très visible. Pour SQLite, cela signifie conserver le numéro de version du schéma dans le nom du fichier de base de données. Pour MySQL, utilisez le nom de la base de données.

  3. Écrire des scripts de migration. 2to3.py, 3to4.py. Ces scripts fonctionnent en deux phases. (1) Recherchez 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 autre traitement. Ces fichiers d'extraction - car ils sont dans la structure appropriée, sont rapides à charger et peuvent facilement être utilisés comme montages de test unitaire. De plus, vous n'avez jamais deux bases de données ouvertes en même temps. Cela rend les scripts légèrement plus simples. Enfin, les fichiers de chargement 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 courant) d'avoir une chirurgie de base de données si profonde qu'un script automatisé ne peut pas facilement mapper les données de l'ancien schéma au nouveau schéma.

14
S.Lott

Utilisez sqlalchemy-migrate .

Il est conçu pour prendre en charge une approche agile de la conception de bases de données et pour faciliter la synchronisation des bases de données de développement et de production, car des modifications de schéma sont nécessaires. Cela facilite la gestion des versions de schéma.

Considérez-le comme un contrôle de version pour votre schéma de base de données. Vous y validez chaque modification de schéma et il pourra avancer/reculer sur les versions de schéma. De cette façon, vous pouvez mettre à niveau un client et il saura exactement quel ensemble de modifications appliquer à la base de données de ce client.

Il fait ce que S.Lott propose dans sa réponse, automatiquement pour vous. Rend une chose difficile facile.

13
nosklo

La meilleure façon de traiter votre problème est de refléter votre schéma au lieu de le faire de manière déclarative. J'ai écrit un article sur l'approche réflexive ici: http://petrushev.wordpress.com/2010/06/16/reflective-approach-on-sqlalchemy-usage/ mais il existe d'autres ressources à ce sujet aussi. De cette manière, chaque fois que vous apportez des modifications à votre schéma, il vous suffit de redémarrer l'application et la réflexion récupérera les nouvelles métadonnées pour les modifications dans les tableaux. C'est assez rapide et sqlalchemy ne le fait qu'une seule fois par processus. Bien sûr, vous devrez gérer les changements de relations que vous apportez vous-même.

1
vonPetrushev