我有一组Sequelize模型。我要使用迁移,而不是数据库同步。
根据本文的介绍,Sequelize CLI似乎可以做到这一点:“当您使用CLI进行模型生成时,您还将免费获得迁移脚本。”
如何使用Sequelize CLI从现有Sequelize模型自动生成迁移?
我有一组Sequelize模型。我要使用迁移,而不是数据库同步。
根据本文的介绍,Sequelize CLI似乎可以做到这一点:“当您使用CLI进行模型生成时,您还将免费获得迁移脚本。”
如何使用Sequelize CLI从现有Sequelize模型自动生成迁移?
Answers:
如果您不想从头开始创建模型,则可以使用以下CLI命令手动生成迁移文件:
sequelize migration:generate --name [name_of_your_migration]
这将生成一个空白的框架迁移文件。尽管它不会将您的模型结构复制到文件中,但我确实比重新生成所有内容更轻松,更干净。注意:请确保从迁移目录的包含目录运行命令;否则,CLI将为您生成一个新的迁移目录
npx sequelize-cli migration:generate --name [name_of_your_migration]
从项目的根目录运行。但是在您这样做之前,您需要告诉 sequelize-cli在何处生成迁移,sequelize-cli使用migrations-path
为此配置的配置。 sequelize.org/master/manual/…–
您不能为现有模型创建迁移脚本。
资源:
如果采用经典方式,则必须通过CLI重新创建模型:
sequelize model:create --name MyUser --attributes first_name:string,last_name:string,bio:text
它将生成以下文件:
models / myuser.js:
"use strict";
module.exports = function(sequelize, DataTypes) {
var MyUser = sequelize.define("MyUser", {
first_name: DataTypes.STRING,
last_name: DataTypes.STRING,
bio: DataTypes.TEXT
}, {
classMethods: {
associate: function(models) {
// associations can be defined here
}
}
});
return MyUser;
};
migrations / 20150210104840-create-my-user.js:
"use strict";
module.exports = {
up: function(migration, DataTypes, done) {
migration.createTable("MyUsers", {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: DataTypes.INTEGER
},
first_name: {
type: DataTypes.STRING
},
last_name: {
type: DataTypes.STRING
},
bio: {
type: DataTypes.TEXT
},
createdAt: {
allowNull: false,
type: DataTypes.DATE
},
updatedAt: {
allowNull: false,
type: DataTypes.DATE
}
}).done(done);
},
down: function(migration, DataTypes, done) {
migration.dropTable("MyUsers").done(done);
}
};
stukko addMigration
在5:40之后键入的时间)。
现在是2020年,其中许多答案不再适用于Sequelize v4 / v5 / v6生态系统。
一个好的答案是说使用sequelize-auto-migrations
,但说明性不足以在您的项目中使用。所以这里有更多颜色...
我的团队使用了,sequelize-auto-migrations
因为原始回购尚未合并到一些关键PR。#56 #57 #58 #59
$ yarn add github:scimonster/sequelize-auto-migrations#a063aa6535a3f580623581bf866cef2d609531ba
编辑 package.json:
"scripts": {
...
"db:makemigrations": "./node_modules/sequelize-auto-migrations/bin/makemigration.js",
...
}
注意:请确保您正在使用git(或某些源代码管理)和数据库备份,以便在出现严重问题时可以撤消这些更改。
.sync()
yarn db:makemigrations --name "mega-migration"
)中的所有内容。01-mega-migration.js
的_current.json
生成的内容。.sync()
或手写迁移,则需要通过将其名称插入SequelizeMeta表中来“伪造”大型迁移。INSERT INTO SequelizeMeta Values ('01-mega-migration.js')
。$ yarn db:makemigrations --name whatever
02-whatever.js
迁移和变化_current.json
,和_current.bak.json
。$ yarn sequelize db:migrate
。removeColumn
和addColumn
。这将丢失生产中的数据。您将需要修改向上和向下操作以renameColumn
代替使用。对于那些对如何使用感到困惑的人
renameColumn
,该代码段将如下所示。(将切换为“ column_name_before”和“ column_name_after”rollbackCommands
)
{
fn: "renameColumn",
params: [
"table_name",
"column_name_before",
"column_name_after",
{
transaction: transaction
}
]
}
如果您进行了大量迁移,则down操作可能无法以一致的顺序完美删除项目。
该库的维护者不会主动对其进行检查。因此,如果开箱即用不适合您,则需要找到其他社区分支或其他解决方案。
--name
选项。它是可选的。然后它将创建01-noname.js
...,您可以手动重命名该文件。
现在,您可以使用npm软件包sequelize-auto-migrations自动生成迁移文件。https://www.npmjs.com/package/sequelize-auto-migrations
使用sequelize-cli,使用
sequelize init
创建您的模型并将其放在您的模型文件夹中。
安装sequelize-auto-migrations:
npm install sequelize-auto-migrations
使用以下命令创建初始迁移文件
node ./node_modules/sequelize-auto-migrations/bin/makemigration --name <initial_migration_name>
运行迁移:
node ./node_modules/sequelize-auto-migrations/bin/runmigration
您也可以从现有数据库自动生成模型,但这超出了问题的范围。
我创建了一个小型的“迁移文件生成器”。它使用创建的文件可以正常工作sequelize db:migrate
-即使使用外键!
您可以在这里找到它:https : //gist.github.com/manuelbieh/ae3b028286db10770c81
我在包含12种不同模型的应用程序中对其进行了测试:
STRING,TEXT,ENUM,INTEGER,BOOLEAN,FLOAT作为数据类型
外键约束(甚至是互惠的(用户属于所有者,团队属于用户作为所有者))
使用索引name
,method
以及unique
性能
尽管它不会自动生成,但是一种基于模型更改生成新迁移的方法是:(假设您使用的是迁移和模型处于同一级别的常规sequelize-cli文件结构)
(与Manuel Bieh的建议相同,但是使用require而不是import)在您的迁移文件中(如果您没有迁移文件,则可以通过执行“ sequelize migration:create
”生成一个),其代码如下:
'use strict';
var models = require("../models/index.js")
module.exports = {
up: function(queryInterface, Sequelize) {
return queryInterface.createTable(models.User.tableName,
models.User.attributes);
},
down: function(queryInterface, Sequelize) {
return queryInterface.dropTable('Users');
}
};
更改用户模型。
sequelize db:migrate:undo:all
sequelize db:migrate
models.sequelize.sync({force: true})
(只是稍微复杂一点)。如果更改模型,则无法更新架构,因为迁移已在运行(这就是您这样做的原因db:migrate:undo:all
)。迁移应版本化您的数据库架构。这是一个很好的示例(我学到了很少的命令),但是我不会在中使用它production
。
如果要与迁移一起创建模型,请使用以下命令:
sequelize model:create --name regions --attributes name:string,status:boolean --underscored
--underscored它用于创建具有下划线的列,例如:-created_at,updated_at或任何其他具有下划线的列,并支持用户定义的具有下划线的列。
我最近尝试了以下方法,该方法似乎很好用,尽管我不确定100%是否可能有任何副作用:
'use strict';
import * as models from "../../models";
module.exports = {
up: function (queryInterface, Sequelize) {
return queryInterface.createTable(models.Role.tableName, models.Role.attributes)
.then(() => queryInterface.createTable(models.Team.tableName, models.Team.attributes))
.then(() => queryInterface.createTable(models.User.tableName, models.User.attributes))
},
down: function (queryInterface, Sequelize) {
...
}
};
当使用进行上述迁移时sequelize db:migrate
,我的控制台会说:
Starting 'db:migrate'...
Finished 'db:migrate' after 91 ms
== 20160113121833-create-tables: migrating =======
== 20160113121833-create-tables: migrated (0.518s)
所有的表都在那里,一切(至少似乎)都按预期工作。如果正确定义了它们,那么所有的关联都在那里。
./tmp
文件夹中)生成静态迁移文件:gist.github.com/manuelbieh/606710b003b5fe448100-正如我上面已经说过的:我不知道是否有任何负面影响,所以使用它慎用!
另一种解决方案是将数据定义放入单独的文件中。
这个想法是将模型和迁移通用的数据写入一个单独的文件,然后在迁移和模型中都需要它。然后,在模型中我们可以添加验证,而迁移已经可以进行了。
为了不使这篇文章充满大量代码,我写了一个GitHub要点。
在此处查看:https://gist.github.com/igorvolnyi/f7989fc64006941a7d7a1a9d5e61be47