Sequelize.js:如何使用迁移和同步

我已经接近准备推出我的项目了。 我有大的计划,推出之后,数据库结构将发生变化 – 现有表中的新列以及新表,以及与现有和新模型的新关联。

我还没有触及Sequelize中的迁移,因为我只有testing数据,我不介意每次数据库更改时清除。

为此,目前我正在运行sync force: true当我的应用程序启动时,如果我已经改变了模型定义,则为sync force: true 。 这将删除所有的表,并从头开始。 我可以省略force选项,让它只创build新表。 但是,如果现有的改变,这是没有用的。

所以一旦我join迁移,事情是如何工作的? 显然,我不希望现有的表格(其中的数据)被清除,所以sync force: true是不可能的。 在其他应用程序中,我已经帮助开发(Laravel和其他框架)作为应用程序部署过程的一部分,我们运行migrate命令来运行任何未决的迁移。 但是在这些应用程序中,第一次迁移有一个骨架数据库,数据库处于开发初期的一段时间 – 第一个alpha版本或其他。 因此,即使是晚会的应用程序的一个实例,也可以通过按顺序运行所有的迁移来一口气加速。

我如何在Sequelize中产生这样的“第一次迁移”? 如果我没有,那么应用程序的新实例将不会有骨架数据库来运行迁移,或者它将在开始时运行同步,并将使数据库处于新状态新的表格等等,但是当它试图运行迁移时,它们是没有意义的,因为它们是用原始数据库和每一个连续的迭代来logging的。

我的思考过程:在每个阶段,初始数据库加上每个迁移顺序应该等于(加或减数据)在sync force: true运行时生成的数据库。 这是因为代码中的模型描述描述了数据库结构。 所以也许如果没有迁移表,我们只运行同步并将所有的迁移标记为已完成,即使它们没有运行。 这是我需要做什么(如何?),或者是Sequelize应该自己做这个,还是我咆哮错误的树? 如果我在正确的领域,肯定应该有一个很好的方式来自动生成大部分的迁移,给定旧模型(通过提交散列?甚至每个迁移可以绑定到一个提交?我承认我在想在一个不可移植的以git为中心的世界中)和新模型。 它可以对结构进行区分,并生成将数据库从旧到新的数据转换后所需的命令,然后开发人员可以进行必要的调整(删除/转换特定的数据等)。

当我用--init命令运行sequelize二进制文件时,它给了我一个空的迁移目录。 当我然后运行sequelize --migrate它使我没有任何内容的SequelizeMeta表,没有其他表。 显然不是,因为该二进制文件不知道如何引导我的应用程序并加载模型。

我肯定错过了什么。

TLDR:我如何设置我的应用程序及其迁移,以便实时应用程序的各种实例可以更新,以及没有传统启动数据库的全新应用程序?

生成“第一次迁移”

在你的情况下,最可靠的方法是几乎手动完成。 我会build议使用sequelize-cli工具。 语法很简单:

 sequelize init ... sequelize model:create --name User --attributes first_name:string,last_name:string,bio:text 

这将创build模型和迁移。 然后,手动合并现有的模型,并使用sequelize-cli生成模型,并使用迁移进行相同的操作。 完成后,擦除数据库(如果可能),然后运行

 sequelize db:migrate 

这将创build模式将迁移。 你只能这样做一次才能切换到适当的模式开发过程(没有同步:强制,但有权威的迁移)。

之后,当您需要更改模式时:

  1. 创build一个迁移: sequelize migration:create
  2. 在你的迁移文件中写下你的function
  3. 根据您在迁移文件中的更改,手动更改模型
  4. 运行sequelize db:migrate

在生产上运行迁移

显然,你不能ssh到生产服务器,并手动运行迁移。 使用umzug , Node.JS的框架不可知的迁移工具在应用程序启动之前执行未完成的迁移。

你可以得到一个待处理/尚未执行的迁移列表,如下所示:

 umzug.pending().then(function (migrations) { // "migrations" will be an Array with the names of // pending migrations. }); 

然后执行迁移( 在callback中 )。 execute方法是一个通用函数,它为每个指定的迁移运行相应的函数:

 umzug.execute({ migrations: ['some-id', 'some-other-id'], method: 'up' }).then(function (migrations) { // "migrations" will be an Array of all executed/reverted migrations. }); 

我的build议是在应用程序启动之前执行,并尝试每次服务路线。 像这样的东西:

 umzug.pending().then(function(migrations) { // "migrations" will be an Array with the names of // pending migrations. umzug.execute({ migrations: migrations, method: 'up' }).then(function(migrations) { // "migrations" will be an Array of all executed/reverted migrations. // start the server app.listen(3000); // do your stuff }); }); 

我现在不能尝试这个,但起初看起来应该可行。

UPD 2016年4月

一年后,仍然有用,所以分享我目前的技巧。 现在,我正在安装sequelize-cli包作为所需的live依赖,然后修改package.json NPM启动脚本,如下所示:

 ... "scripts": { "dev": "grunt && sequelize db:migrate && sequelize db:seed:all && node bin/www", "start": "sequelize db:migrate && sequelize db:seed:all && node bin/www" }, ... 

我需要在生产服务器上做的唯一事情是npm start 。 该命令将运行所有迁移,应用所有的播种器并启动应用程序服务器。 不需要手动调用umzug。

只是自己学习,但我想我会build议现在使用迁移,所以你习惯了他们。 我发现最好的办法是弄清楚迁移过程中发生的事情是看看由sequelize.sync()创build的表上的sql,然后从那里构build迁移。

迁移-c [迁移名称]

将在迁移目录中创build模板迁移文件。 然后,您可以填写您需要创build的字段。 这个文件需要包含createdAt / updatedAt,关联所需的字段等等。对于初始表的创build,应该有:

migration.dropTable( 'MyTable的');

但是对表结构的后续更新可以省去这个,只是使用alter table。

 ./node_modules/.bin/sequelize --migrate 

创build示例如下所示:

 module.exports = { up: function(migration, DataTypes, done) { migration.createTable( 'MyTable', { id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true }, bigString: {type: DataTypes.TEXT, allowNull: false}, MyOtherTableId: DataTypes.INTEGER, createdAt: { type: DataTypes.DATE }, updatedAt: { type: DataTypes.DATE } }); done(); }, down: function(migration, DataTypes, done) { migration.dropTable('MyTable'); done(); } 

从开始重做:

 ./node_modules/.bin/sequelize --migrate --undo ./node_modules/.bin/sequelize --migrate 

我正在使用咖啡来运行种子文件来填充表后:

 coffee server/seed.coffee 

这只是一个创buildfunction,它看起来像这样:

 user = db.User.create username: 'bob' password: 'suruncle' email: 'bob@bob.com' .success (user) -> console.log 'added user' user_id = user.id myTable = [ field1: 'womp' field2: 'rat' subModel: [ field1: 'womp' , field1: 'rat' ] ] 

请记住,在模型中将sync()从索引中取出,否则将覆盖迁移和种子所做的操作。

文档当然在http://sequelize.readthedocs.org/en/latest/docs/migrations/ 。 但基本的答案是你必须添加一切,以指定你需要的领域。 它不适合你:-(

对于开发 ,现在可以通过改变结构来同步当前表格。 使用来自sequelize github repo的最新版本,现在可以使用alter参数运行同步。

 Table.sync({alter: true}) 

来自文档的警告:

改变表格以适应模型。 不build议用于生产用途。 删除模型中已删除或其types已更改的列中的数据。

使用版本。 应用程序的版本取决于数据库的版本。 如果新版本需要更新数据库,请为其创build迁移。

更新:我决定放弃迁移( KISS ),并在需要时运行脚本update_db(sync forse:false)。

Sequelize可以运行任意SQL。 但要小心它是asynchronous的

我会做的是:

  • 生成迁移(用作第一次迁移);
  • 转储你的数据库,像这样: mysql_dump -uUSER -pPASS DBNAME > FILE.SQL
  • 将完整转储粘贴为文本(危险),或者使用Node中的完整转储加载文件:
    • 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');
  • 在Sequelize迁移上运行此转储:
 module.exports = { up: function (migration, DataTypes) { var baseSQL = "whatever" // I recommend loading a file migration.migrator.sequelize.query(baseSQL); } } 

这应该照顾build立数据库,虽然asynchronous的事情可能成为一个问题。 如果发生这种情况,我会考虑延迟返回up序列化函数,直到asynchronousquery函数完成。

关于mysql_dump的更多信息: http ://dev.mysql.com/doc/refman/5.1/en/mysqldump.html
关于续集迁移的更多信息: http ://sequelize.readthedocs.org/en/latest/docs/migrations/
有关从Sequelize迁移中运行SQL的更多信息: https : //github.com/sequelize/sequelize/issues/313

现在用新的续集迁移非常简单。

这是你可以做的一个例子。

  'use strict'; var Promise = require('bluebird'), fs = require('fs'); module.exports = { up: function (queryInterface, Sequelize) { return Promise .resolve() .then(function() { return fs.readFileSync(__dirname + '/../initial-db.sql', 'utf-8'); }) .then(function (initialSchema) { return queryInterface.sequelize.query(initialSchema); }) }, down: function (queryInterface, Sequelize) { return Promise .resolve() .then(function() { return fs.readFileSync(__dirname + '/../drop-initial-db.sql', 'utf-8'); }) .then(function (dropSql) { return queryInterface.sequelize.query(dropSql); }); } }; 

记住你必须设置:

"dialectOptions": { "multipleStatements": true }

在数据库configuration。

有点晚了,在阅读文档之后,你不需要首先进行迁移。 你所要做的就是调用sync来创build表格。

sequelize.sync()

您也可以通过执行以下操作来运行简单的模型同步:

Project.sync()但我认为sequelize.sync()是您的项目更有用的一般情况下(只要您在开始时导入好模型)。

(取自http://sequelizejs.com/docs/latest/models#database-synchronization

这将创build所有的初始结构。 之后,您将只需创build迁移以演变您的模式。

希望能帮助到你。

这是我目前的工作stream程。 我接受build议。

  1. 设置sequelize来创build不存在的表
  2. 设置sequelize删除并重新创build一个名为_blank的空白数据库中的所有表
  3. 使用mysql工具比较_blank和使用该工具同步更改。 仍然在寻找一个经济实惠的工具,可以在Mac上做到这一点。 MySql工作台看起来像您可以从现有模式导入模型,然后同步模式。 试图找出如何通过命令行来实现这一点。

这样,你不必手动更新迁移表,不必担心手指发胖,但你仍然得到一个ORM。

朋友我有同样的问题,并设法了解如何使用它们。

我开始没有ORM sequelize因此我已经有一个数据模型。
我必须使用sequelize-auto自动生成模型,并使用您创build的文件生成他们的迁移https://gist.github.com/ahelord/a7a7d293695b71aadf04157f0f7dee64并同步(; {Force: false}
这是dev.I将不得不版本的模型和迁移,并执行他们每次我拉代码。

在生产服务器只在楼上,所以你只需要运行迁移,并在每个提交pipe理,因为你将版本的模型,而不会停止后端