Ich bin kurz davor, mein Projekt startbereit zu machen. Ich habe große Pläne für nach dem Start und die Datenbankstruktur wird sich ändern - neue Spalten in vorhandenen Tabellen sowie neue Tabellen und neue Zuordnungen zu vorhandenen und neuen Modellen.
Ich habe Migrationen in Sequelize noch nicht berührt, da ich nur Testdaten hatte, die ich gerne jedes Mal lösche, wenn sich die Datenbank ändert.
Zu diesem Zweck werde ich derzeit beim Start sync force: true
meiner App ausgeführt, wenn ich die Modelldefinitionen geändert habe. Dadurch werden alle Tabellen gelöscht und von Grund auf neu erstellt. Ich könnte die force
Option weglassen , nur neue Tabellen erstellen zu lassen. Wenn sich jedoch vorhandene geändert haben, ist dies nicht sinnvoll.
Wie funktionieren die Dinge, wenn ich Migrationen hinzufüge? Natürlich möchte ich nicht, dass vorhandene Tabellen (mit Daten darin) gelöscht werden, daher sync force: true
kommt dies nicht in Frage. Bei anderen Apps, an deren Entwicklung ich mitgewirkt habe (Laravel und andere Frameworks), führen wir im Rahmen des Bereitstellungsverfahrens der App den Befehl migrate aus, um ausstehende Migrationen auszuführen. In diesen Apps verfügt die allererste Migration jedoch über eine Skelettdatenbank, wobei sich die Datenbank in dem Zustand befindet, in dem sie sich einige Zeit zu Beginn der Entwicklung befand - die erste Alpha-Version oder was auch immer. So kann auch eine Instanz der App, die zu spät zur Party kommt, auf einmal auf den neuesten Stand gebracht werden, indem alle Migrationen nacheinander ausgeführt werden.
Wie generiere ich eine solche "erste Migration" in Sequelize? Wenn ich keine habe, hat eine neue Instanz der App in der Zukunft entweder keine Skelettdatenbank, auf der die Migrationen ausgeführt werden können, oder sie wird zu Beginn synchronisiert und die Datenbank mit allen in den neuen Status versetzt die neuen Tabellen usw., aber wenn dann versucht wird, die Migrationen auszuführen, sind sie nicht sinnvoll, da sie mit der ursprünglichen Datenbank und jeder nachfolgenden Iteration geschrieben wurden.
Mein Denkprozess: In jeder Phase sollte die anfängliche Datenbank plus jede Migration nacheinander gleich (plus oder minus Daten) der Datenbank sein, die wann generiert wurde sync force: true
es läuft. Dies liegt daran, dass die Modellbeschreibungen im Code die Datenbankstruktur beschreiben. Wenn es also keine Migrationstabelle gibt, führen wir einfach die Synchronisierung aus und markieren alle Migrationen als abgeschlossen, obwohl sie nicht ausgeführt wurden. Muss ich das tun (wie?) Oder soll Sequelize das selbst tun oder belle ich den falschen Baum an? Und wenn ich mich im richtigen Bereich befinde, sollte es angesichts der alten Modelle (durch Commit-Hash? Oder könnte jede Migration an ein Commit gebunden sein?) Sicherlich eine gute Möglichkeit geben, den größten Teil einer Migration automatisch zu generieren. Ich gebe zu, dass ich denke in einem nicht tragbaren git-zentrierten Universum) und den neuen Modellen. Es kann die Struktur unterscheiden und die Befehle generieren, die zum Transformieren der Datenbank von alt zu neu und zurück erforderlich sind. Anschließend kann der Entwickler die erforderlichen Änderungen vornehmen (Löschen / Übertragen bestimmter Daten usw.).
Wenn ich die Sequelize-Binärdatei mit dem --init
Befehl ausführe , wird mir ein leeres Migrationsverzeichnis angezeigt . Wenn ich es dann ausführe sequelize --migrate
, erhalte ich eine SequelizeMeta-Tabelle mit nichts darin, keinen anderen Tabellen. Offensichtlich nicht, da diese Binärdatei nicht weiß, wie ich meine App booten und die Modelle laden kann.
Mir muss etwas fehlen.
TLDR: Wie richte ich meine App und ihre Migrationen ein, damit verschiedene Instanzen der Live-App auf den neuesten Stand gebracht werden können, sowie eine brandneue App ohne alte Startdatenbank?
sync
, besteht die Idee darin, dass Migrationen die gesamte Datenbank "generieren", sodass es an sich schon ein Problem ist, sich auf ein Skelett zu verlassen. Der Ruby on Rails-Workflow verwendet beispielsweise Migrationen für alles und ist ziemlich beeindruckend, wenn Sie sich erst einmal daran gewöhnt haben. Bearbeiten: Und ja, ich habe bemerkt, dass diese Frage ziemlich alt ist, aber da es nie eine zufriedenstellende Antwort gab und die Leute hierher kommen könnten, um Rat zu suchen, dachte ich, ich sollte dazu beitragen.Antworten:
Generieren der "ersten Migration"
In Ihrem Fall ist es am zuverlässigsten, dies fast manuell zu tun. Ich würde vorschlagen, das Tool sequelize-cli zu verwenden. Die Syntax ist ziemlich einfach:
Dadurch werden sowohl Modell- als auch Migration erstellt. Führen Sie dann Ihre vorhandenen Modelle manuell mit den mit sequelize-cli generierten Modellen zusammen und machen Sie dasselbe mit Migrationen. Löschen Sie anschließend die Datenbank (falls möglich) und führen Sie sie aus
Dadurch werden Schema-Migrationen erstellt. Sie sollten dies nur einmal tun, um zum richtigen Prozess der Schemaentwicklung zu wechseln (ohne sync: force, aber mit autorisierenden Migrationen).
Wenn Sie später das Schema ändern müssen:
sequelize migration:create
sequelize db:migrate
Ausführen von Migrationen in der Produktion
Offensichtlich können Sie nicht zum Produktionsserver ssh und Migrationen von Hand ausführen. Verwenden Sie umzug , Framework Agnostic Migration Tool für Node.JS, um ausstehende Migrationen durchzuführen, bevor die App gestartet wird.
Sie können eine Liste ausstehender / noch nicht ausgeführter Migrationen wie folgt erhalten:
Führen Sie dann Migrationen aus ( innerhalb des Rückrufs ). Die Methode execute ist eine Allzweckfunktion, die für jede angegebene Migration die entsprechende Funktion ausführt:
Mein Vorschlag ist, dies vor dem Start der App zu tun und jedes Mal zu versuchen, Routen zu bedienen. Etwas wie das:
Ich kann das momentan nicht ausprobieren, aber auf den ersten Blick sollte es funktionieren.
UPD Apr. 2016
Nach einem Jahr immer noch nützlich, also teile meine aktuellen Tipps. Im Moment installiere ich das
sequelize-cli
Paket nach Bedarf unter Live- Abhängigkeit und ändere dann die NPM-Startskriptepackage.json
wie folgt:Das einzige, was ich auf dem Produktionsserver tun muss, ist
npm start
. Dieser Befehl führt alle Migrationen aus, wendet alle Seeders an und startet den App-Server. Umzug muss nicht manuell aufgerufen werden.quelle
pending
und dannexecute
und einfach tunumzug.up().then(function (migrations) { app.listen(3000); })
. Gemäß der umzug-Dokumentation werden alle ausstehenden Migrationen ausgeführt.Ich lerne das nur selbst, aber ich denke, ich würde empfehlen, jetzt Migrationen zu verwenden, damit Sie sich daran gewöhnen. Ich habe herausgefunden, dass das Beste, um herauszufinden, was in der Migration vor sich geht, darin besteht, die SQL in den von erstellten Tabellen zu betrachten
sequelize.sync()
und dann die Migrationen von dort aus zu erstellen.Erstellt die Vorlagenmigrationsdatei in einem Migrationsverzeichnis. Sie können es dann mit den Feldern füllen, die Sie erstellen müssen. Diese Datei muss
createdAt
/updatedAt
, Felder enthalten, die für Assoziationen usw. benötigt werden.Für die anfängliche Tabellenerstellung sollte down:
Nachfolgende Aktualisierungen der Tabellenstruktur können dies jedoch auslassen und nur alter table verwenden.
Ein Beispiel zum Erstellen würde folgendermaßen aussehen:
So wiederholen Sie von Anfang an:
Ich verwende Kaffee, um eine Seed-Datei auszuführen und die Tabellen danach zu füllen:
Dies hat nur eine Erstellungsfunktion, die ungefähr so aussieht:
Denken Sie daran, Ihren
sync()
Index in Ihren Modellen zu deaktivieren, da sonst überschrieben wird, was die Migrationen und der Startwert bewirken.Die Dokumente finden Sie natürlich unter http://sequelize.readthedocs.org/en/latest/docs/migrations/ . Die grundlegende Antwort ist jedoch, dass Sie alles in sich selbst hinzufügen müssen, um die Felder anzugeben, die Sie benötigen. Es macht es nicht für dich.
quelle
sequelize.sync()
dann kein generiertes Skript haben können, das alle Basistabellen und -indizes als erste Migration erstellt (ähnlich wie bei Rails)schema.rb
. Nach dem Lesen scheint es am besten zu sein, Ihr ursprüngliches Schema zu exportieren Als SQL setzen Sie es dannexec
in Ihrer ersten Migration in eine große Aussage. Von dort aus führen Sie dann inkrementelle Änderungen an einem bekannten Startpunkt "Version 1.0" durch.Für die Entwicklung besteht jetzt die Möglichkeit, die aktuellen Tabellen durch Ändern ihrer Struktur zu synchronisieren. Mit der neuesten Version aus dem Sequelize Github Repo können Sie jetzt die Synchronisierung mit dem
alter
Parameter ausführen .Eine Einschränkung aus den Dokumenten:
quelle
Jetzt mit der neuen Folge ist die Migration sehr einfach.
Dies ist ein Beispiel dafür, was Sie tun können.
Denken Sie daran, Sie müssen einstellen:
"dialectOptions": { "multipleStatements": true }
auf Datenbankkonfiguration.
quelle
Verwenden Sie die Version. Die Version der Anwendung hängt von der Version der Datenbank ab. Wenn für die neue Version eine Aktualisierung einer Datenbank erforderlich ist, erstellen Sie eine Migration dafür.
update: Ich habe beschlossen, die Migration ( KISS ) abzubrechen und das Skript update_db (sync forse: false) auszuführen, wenn es benötigt wird.
quelle
sync()
und die Migrationen manuell vom Schema der Modelle der älteren Version in die Modelle der neueren Version schreiben?Ein bisschen spät, und nachdem Sie die Dokumentation gelesen haben, müssen Sie nicht die erste Migration haben, über die Sie sprechen. Sie müssen lediglich aufrufen
sync
, um die Tabellen zu erstellen.sequelize.sync()
Sie können auch eine einfache Modellsynchronisierung ausführen, indem Sie Folgendes ausführen:
Project.sync()
Aber ich denke, dassequelize.sync()
ist ein nützlicherer allgemeiner Fall für Ihr Projekt (solange Sie die guten Modelle zur Startzeit importieren).(entnommen aus http://sequelizejs.com/docs/latest/models#database-synchronization )
Dadurch werden alle anfänglichen Strukturen erstellt. Danach müssen Sie nur noch Migrationen erstellen, um Ihre Schemas weiterzuentwickeln.
ich hoffe es hilft.
quelle
sequelize.sync()
und was es tut.Sequelize kann beliebiges SQL asynchron ausführen .
Was ich tun würde ist:
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');
Das sollte sich um die Einrichtung der Datenbank kümmern, auch wenn die asynchrone Sache zu einem Problem werden kann. In diesem Fall würde ich nach einer Möglichkeit suchen, die Rückgabe der
up
Sequelize-Funktion zu verschieben, bis die Async-query
Funktion abgeschlossen ist.Mehr über mysql_dump: http://dev.mysql.com/doc/refman/5.1/en/mysqldump.html
Weitere Informationen zu Sequelize Migrations: http://sequelize.readthedocs.org/en/latest/docs/migrations/
Weitere Informationen zu Ausführen von SQL in Sequelize Migration: https://github.com/sequelize/sequelize/issues/313
quelle
Hier ist mein aktueller Workflow. Ich bin offen für Vorschläge.
Auf diese Weise müssen Sie die Migrationstabelle nicht manuell aktualisieren und müssen sich um dicke Finger kümmern, aber Sie erhalten trotzdem einen ORM.
quelle
Freund Ich hatte die gleiche Frage und konnte verstehen, wie man sie benutzt.
Ich habe ohne ORM-Fortsetzung angefangen, daher hatte ich bereits ein Datenmodell.
Ich musste die Modelle automatisch mit sequelize-auto generieren und ihre Migrationen mit dieser Datei generieren, die Sie unter https://gist.github.com/ahelord/a7a7d293695b71aadf04157f0f7dee64 erstellen und synchronisieren (
{Force: false}
)Dies ist in dev.I müsste versioniert werden das Modell und die Migrationen und führen sie jedes Mal aus, wenn ich den Code ziehe.
In der Produktion befindet sich der Server nur im Obergeschoss, sodass Sie nur Migrationen ausführen und in jedem Commit verwalten müssen, wie Sie das Modell versionieren, ohne das Backend anzuhalten
quelle
Ich habe diesen Beitrag und ähnliche Fragen durchgesehen, er hat mich nicht wirklich beantwortet. Migrationen sind nützlich, um lokale Datenbanken hochzufahren und Daten in der Produktion zu aktualisieren
Ich habe die Frage hier gestellt und auch beantwortet: Workflow für die Bearbeitung von Migrationen und Initialisierungen nacheinander?
TL-DR-Version für ein Greenfield-Projekt
.sql
Datei verschiebensequelize init:migrate
den Ordner aus, in dem Sie sichmodels
befindensequelize migration:generate --name [name_of_your_migration]
mit dieser allgemeinen Ordnerstruktur
sequelize migration:generate --name [name_of_your_migration]
up
unddown
Migrationspfaden vor. Dies sind Ihre ALTER-Anweisungen zum Ändern von Spaltennamen, DELETE, ADD-Spalten usw.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
unter https://github.com/sequelize/sequelize-autoSie können git verwenden, um Difflogs in Ihrem Modell anzuzeigen. Es sollten nur Änderungen vorgenommen werden, die Änderungen im Datenbankmodell widerspiegeln. Als Randnotiz: Ändern Sie das niemals
models
direkt, wenn Sie es verwendensequelize auto
, da dies sie für Sie generiert. Ebenso sollten Sie Ihr Datenbankschema nicht mehr direkt mit SQL-Dateien ändern, vorausgesetzt, dies ist eine Option, da Sie diese importieren können.sql
Dateien auch könnenJetzt ist Ihr Datenbankschema auf dem neuesten Stand, und Sie sind offiziell umgezogen, um nur Datenbankmigrationen fortzusetzen.
Alles ist versioniert. Dies ist der ideale Workflow für Datenbank- und Backend-Entwickler
quelle
Es gibt noch einen einfacheren Weg (Sequalize vermeiden). Welches geht so:
Sie geben einen Befehl in Ihr Projekt ein: npm run migrate: new
Dadurch werden 3 Dateien erstellt. Eine js-Datei und zwei SQL-Dateien mit den Namen up und down
Damit dies funktioniert, schauen Sie sich bitte das Modul db-migrate an .
Sobald Sie es eingerichtet haben (was nicht schwierig ist), ist das Ändern Ihrer Datenbank sehr einfach und spart viel Zeit.
quelle