Je suis sur le point d'avoir mon projet prêt à démarrer. J'ai de grands projets pour après le lancement et la structure de la base de données va changer - de nouvelles colonnes dans les tables existantes ainsi que de nouvelles tables, et de nouvelles associations à des modèles existants et nouveaux.
Je n'ai pas encore touché aux migrations dans Sequelize, car je n'ai eu que des données de test que je ne crains pas d'effacer à chaque fois que la base de données change.
À cette fin, j'exécute actuellement sync force: true
lorsque mon application démarre, si j'ai changé les définitions de modèle. Cela supprime toutes les tables et les crée à partir de zéro. Je pourrais omettre l' force
option de ne créer que de nouvelles tables. Mais si ceux existants ont changé, cela n'est pas utile.
Donc, une fois que j'ajoute des migrations, comment les choses fonctionnent-elles? Évidemment, je ne veux pas que les tables existantes (contenant des données) soient effacées, c'est donc sync force: true
hors de question. Sur d'autres applications que j'ai aidé à développer (Laravel et autres frameworks) dans le cadre de la procédure de déploiement de l'application, nous exécutons la commande migrate pour exécuter toutes les migrations en attente. Mais dans ces applications, la toute première migration a une base de données squelette, avec la base de données dans l'état où elle était au début du développement - la première version alpha ou autre. Ainsi, même une instance de l'application en retard à la fête peut se mettre à niveau en une seule fois, en exécutant toutes les migrations dans l'ordre.
Comment générer une telle "première migration" dans Sequelize? Si je n'en ai pas, une nouvelle instance de l'application en aval de la ligne n'aura pas de base de données squelette sur laquelle exécuter les migrations, ou elle se synchronisera au début et rendra la base de données dans le nouvel état avec tous les nouvelles tables, etc., mais quand il essaie d'exécuter les migrations, elles n'auront aucun sens, car elles ont été écrites avec la base de données d'origine et chaque itération successive à l'esprit.
Ma réflexion: à chaque étape, la base de données initiale plus chaque migration en séquence doit être égale (plus ou moins de données) à la base de données générée lorsque sync force: true
est exécuté. En effet, les descriptions de modèle dans le code décrivent la structure de la base de données. Alors peut-être que s'il n'y a pas de table de migration, nous exécutons simplement la synchronisation et marquons toutes les migrations comme terminées, même si elles n'ont pas été exécutées. Est-ce ce que je dois faire (comment?), Ou Sequelize est-il censé le faire lui-même, ou est-ce que je suis en train d'aboyer le mauvais arbre? Et si je suis dans le bon domaine, il devrait sûrement y avoir un bon moyen de générer automatiquement la majeure partie d'une migration, étant donné les anciens modèles (par commit hash? Ou même chaque migration pourrait-elle être liée à un commit? Je concède que je pense dans un univers non portable centré sur git) et les nouveaux modèles. Il peut modifier la structure et générer les commandes nécessaires pour transformer la base de données d'ancienne en nouvelle, et inversement, puis le développeur peut entrer et apporter les modifications nécessaires (suppression / transition de données particulières, etc.).
Lorsque j'exécute le binaire sequelize avec la --init
commande, il me donne un répertoire de migrations vide. Quand je l'exécute, sequelize --migrate
cela me fait une table SequelizeMeta avec rien dedans, pas d'autres tables. Evidemment non, car ce binaire ne sait pas comment démarrer mon application et charger les modèles.
J'ai dû louper quelque chose.
TLDR: comment configurer mon application et ses migrations afin que diverses instances de l'application en direct puissent être mises à jour, ainsi qu'une toute nouvelle application sans base de données de départ héritée?
sync
pour le moment, l'idée est que les migrations "génèrent" la base de données entière, donc s'appuyer sur un squelette est en soi un problème. Le flux de travail Ruby on Rails, par exemple, utilise Migrations pour tout, et c'est assez génial une fois que vous vous y êtes habitué. Edit: Et oui, j'ai remarqué que cette question est assez ancienne, mais comme il n'y a jamais eu de réponse satisfaisante et que les gens peuvent venir ici pour chercher des conseils, j'ai pensé que je devrais contribuer.Réponses:
Générer la "première migration"
Dans votre cas, le moyen le plus fiable est de le faire presque manuellement. Je suggérerais d'utiliser l' outil sequelize-cli . La syntaxe est plutôt simple:
Cela créera à la fois le modèle ET la migration. Ensuite, fusionnez manuellement vos modèles existants avec ceux générés avec sequelize-cli, et faites de même avec les migrations. Après cela, effacez la base de données (si possible) et exécutez
Cela créera des migrations de schéma. Vous ne devez le faire qu'une seule fois pour passer au processus approprié de développement de schéma (sans sync: force, mais avec des migrations faisant autorité).
Plus tard, lorsque vous aurez besoin de changer de schéma:
sequelize migration:create
sequelize db:migrate
Exécution de migrations en production
De toute évidence, vous ne pouvez pas effectuer de ssh vers le serveur de production et exécuter des migrations manuellement. Utilisez umzug , outil de migration indépendant du framework pour Node.JS pour effectuer des migrations en attente avant le démarrage de l'application.
Vous pouvez obtenir une liste des migrations en attente / non encore exécutées comme ceci:
Puis exécutez les migrations ( callback interne ). La méthode execute est une fonction à usage général qui exécute pour chaque migration spécifiée la fonction respective:
Et ma suggestion est de le faire avant le démarrage de l'application et d'essayer de desservir les itinéraires à chaque fois. Quelque chose comme ça:
Je ne peux pas essayer cela pour le moment, mais à première vue, cela devrait fonctionner.
UPD avril 2016
Au bout d'un an, toujours utile, donc partager mes conseils actuels. Pour l' instant, j'installe
sequelize-cli
paquet au besoin en direct dépendance, puis modifier les scripts de NPMpackage.json
comme ceci:La seule chose que je dois faire sur le serveur de production est
npm start
. Cette commande exécutera toutes les migrations, appliquera tous les seeders et démarrera le serveur d'applications. Pas besoin d'appeler umzug manuellement.la source
pending
puisexecute
et juste faireumzug.up().then(function (migrations) { app.listen(3000); })
. Selon la documentation umzug, cela exécutera toutes les migrations en attente.Je viens d'apprendre cela moi-même, mais je pense que je recommanderais d'utiliser les migrations maintenant pour que vous vous y habituiez. J'ai trouvé que la meilleure chose pour comprendre ce qui se passe dans la migration est de regarder le sql sur les tables créées par
sequelize.sync()
, puis de créer les migrations à partir de là.Créera le fichier de migration de modèle dans un répertoire de migrations. Vous pouvez ensuite le remplir avec les champs dont vous avez besoin. Ce fichier devra inclure
createdAt
/updatedAt
, les champs nécessaires aux associations, etc.Pour la création initiale de la table, down devrait avoir:
Mais les mises à jour ultérieures de la structure de la table peuvent laisser cela de côté et utiliser simplement alter table.
Un exemple de création ressemblerait à ceci:
Pour refaire depuis le début:
J'utilise du café pour exécuter un fichier de départ pour remplir les tables après:
Cela a juste une fonction de création qui ressemble à quelque chose comme:
N'oubliez pas de retirer votre
sync()
index dans vos modèles, sinon il écrasera ce que font les migrations et les semences.Les documents sont à http://sequelize.readthedocs.org/en/latest/docs/migrations/ bien sûr. Mais la réponse de base est que vous devez tout ajouter en vous-même pour spécifier les champs dont vous avez besoin. Cela ne le fait pas pour vous.
la source
sequelize.sync()
avoir un script généré qui crée toutes les tables de base et tous les index lors de votre première migration (similaire à rails 'schema.rb
.) Après avoir lu ceci, il semble que votre meilleur pari pourrait être d'exporter votre schéma initial en tant que sql, puis mettez-le dans une grandeexec
déclaration lors de votre toute première migration. Ensuite, à partir de là, vous exécutez des modifications incrémentielles par rapport à un point de départ connu de la «version 1.0».Pour le développement , il existe maintenant une option pour synchroniser les tables actuelles en modifiant leur structure. En utilisant la dernière version du repo github sequelize , vous pouvez maintenant exécuter la synchronisation avec le
alter
paramètre.Une mise en garde de la documentation:
la source
Désormais, avec la nouvelle migration sequelize, c'est très simple.
Voici un exemple de ce que vous pouvez faire.
N'oubliez pas que vous devez définir:
"dialectOptions": { "multipleStatements": true }
sur la configuration de la base de données.
la source
Utilisez la version. La version de l'application dépend de la version de la base de données. Si la nouvelle version nécessite une mise à jour d'une base de données, créez une migration pour celle-ci.
mise à jour: j'ai décidé d'abandonner la migration ( KISS ) et d'exécuter le script update_db (sync forse: false) quand cela est nécessaire.
la source
sync()
du tout et que j'ai besoin d'écrire manuellement les migrations du schéma des modèles de l'ancienne version vers les modèles de la nouvelle version?Un peu tard, et après avoir lu la documentation, vous n'avez pas besoin d'avoir cette première migration dont vous parlez. Tout ce que vous avez à faire est d'appeler
sync
pour créer les tables.sequelize.sync()
Vous pouvez également exécuter une synchronisation de modèle simple en faisant quelque chose comme:
Project.sync()
mais je pense quesequelize.sync()
c'est un cas général plus utile pour votre projet (tant que vous importez les bons modèles au moment du démarrage).(extrait de http://sequelizejs.com/docs/latest/models#database-synchronization )
Cela créera toutes les structures initiales . Ensuite, vous n'aurez plus qu'à créer des migrations pour faire évoluer vos schémas.
J'espère que ça aide.
la source
sequelize.sync()
ce qu'il fait.Sequelize peut exécuter du SQL arbitraire de manière asynchrone .
Ce que je ferais, c'est:
mysql_dump -uUSER -pPASS DBNAME > FILE.SQL
var baseSQL = "LOTS OF SQL and it's EVIL because you gotta put \ backslashes before line breakes and \"quotes\" and/or sum" + " one string for each line, or everything will break";
var baseSQL = fs.readFileSync('../seed/baseDump.sql');
Cela devrait prendre en charge la configuration de la base de données, bien que la chose asynchrone puisse devenir un problème. Si cela se produit, je chercherais un moyen de différer le retour de la
up
fonction sequelize jusqu'à l'asyncquery
fonction soit terminée.En savoir plus sur mysql_dump: http://dev.mysql.com/doc/refman/5.1/en/mysqldump.html En
savoir plus sur Sequelize Migrations: http://sequelize.readthedocs.org/en/latest/docs/migrations/ En
savoir plus Exécution de SQL depuis Sequelize Migration: https://github.com/sequelize/sequelize/issues/313
la source
Voici mon flux de travail actuel. Je suis ouvert aux suggestions.
De cette façon, vous n'avez pas à mettre à jour manuellement la table des migrations et à vous soucier des gros doigts, mais vous obtenez toujours un ORM.
la source
Ami, j'ai eu la même question et j'ai réussi à comprendre comment les utiliser.
J'ai commencé sans séquelle ORM donc j'avais déjà un modèle de données.
J'ai dû générer les modèles automatiquement avec sequelize-auto et générer leurs migrations avec ce fichier que vous créez https://gist.github.com/ahelord/a7a7d293695b71aadf04157f0f7dee64 et que vous mettez en synchronisation (
{Force: false}
)C'est en dev, je devrais la version le modèle et les migrations et les exécuter à chaque fois que je tire le code.
En production, le serveur n'est qu'à l'étage, vous n'avez donc qu'à exécuter des migrations et à chaque commit, gérez comme vous allez versionner le modèle sans arrêter le backend
la source
J'ai parcouru ce post et des questions similaires, cela ne m'a pas vraiment répondu. Les migrations sont utiles pour lancer des bases de données locales et pour mettre à jour des données en production
J'ai posé la question ici et y ai également répondu: Workflow pour gérer les migrations de séquelles et l'initialisation?
Version TL-DR pour un projet greenfield
.sql
fichier entiersequelize init:migrate
dans le dossier où vous vousmodels
trouvezsequelize migration:generate --name [name_of_your_migration]
avec cette structure générale de dossiers
sequelize migration:generate --name [name_of_your_migration]
up
etdown
. Ce sont vos instructions ALTER pour changer les noms de colonne, DELETE, ADD colonnes, etc.sequelize db:migrate
npm install sequelize-auto
.sequelize-auto -o "./models" -d sequelize_auto_test -h localhost -u my_username -p 5432 -x my_password -e postgres
trouvée sous https://github.com/sequelize/sequelize-autoVous pouvez utiliser git pour voir les difflogs sur votre modèle, il ne devrait y avoir que des changements reflétant les changements dans le modèle de base de données. En remarque, ne modifiez jamais le
models
directement si vous utilisezsequelize auto
, car cela les générera pour vous. De même, vous ne devez plus modifier le schéma de votre base de données directement avec les fichiers SQL, à condition qu'il s'agisse d'une option car vous pouvez les importer.sql
fichiersMaintenant, votre schéma de base de données est à jour et vous êtes officiellement passé à la séquelle des migrations de bases de données uniquement.
Tout est contrôlé par version. C'est le flux de travail idéal pour les développeurs de bases de données et de backend
la source
Il existe un moyen encore plus simple (éviter Sequalize). Ce qui va comme ceci:
Vous tapez une commande dans votre projet: npm run migrate: new
Cela crée 3 fichiers. Un fichier js et deux fichiers sql nommés haut et bas
Pour que cela fonctionne, veuillez consulter le module db-migrate .
Une fois que vous l'avez configuré (ce qui n'est pas difficile), changer votre base de données est vraiment facile et vous fait gagner beaucoup de temps.
la source