sequelize.sync()上的force选项有什么作用?
sequelize.sync({
force: true
});
具体来说,我有兴趣知道什么力:假吗?它不会将架构与数据库同步吗?
有没有正式的续集文档?我只能在文档中找到示例。
答案 0 :(得分:40)
(或多或少)正式文档和API参考可以在http://sequelize.readthedocs.org/en/latest/api/sequelize/#sync
找到对于您的问题:force: true
在尝试创建表格之前添加DROP TABLE IF EXISTS
- 如果您强制使用,则会覆盖现有表格。
答案 1 :(得分:29)
OP问的是force: false
做了什么,这也是我想知道的,所以其余部分就是这样。
对我来说,主要的问题是个别领域没有同步(这是我希望的,来自Waterline ORM)。这意味着,如果您有force: false
且表存在,则不会执行任何字段添加/修改/删除。
beforeSync
个钩子force: true
,if not exists
afterSync
个钩子以下是current code from the github repo供参考:
<强> lib.model.js
强>
Model.prototype.sync = function(options) {
options = options || {};
options.hooks = options.hooks === undefined ? true : !!options.hooks;
options = Utils._.extend({}, this.options, options);
var self = this
, attributes = this.tableAttributes;
return Promise.try(function () {
if (options.hooks) {
return self.runHooks('beforeSync', options);
}
}).then(function () {
if (options.force) {
return self.drop(options);
}
}).then(function () {
return self.QueryInterface.createTable(self.getTableName(options), attributes, options, self);
}).then(function () {
return self.QueryInterface.showIndex(self.getTableName(options), options);
}).then(function (indexes) {
// Assign an auto-generated name to indexes which are not named by the user
self.options.indexes = self.QueryInterface.nameIndexes(self.options.indexes, self.tableName);
indexes = _.filter(self.options.indexes, function (item1) {
return !_.some(indexes, function (item2) {
return item1.name === item2.name;
});
});
return Promise.map(indexes, function (index) {
return self.QueryInterface.addIndex(self.getTableName(options), _.assign({logging: options.logging, benchmark: options.benchmark}, index), self.tableName);
});
}).then(function () {
if (options.hooks) {
return self.runHooks('afterSync', options);
}
}).return(this);
};
答案 2 :(得分:0)
最小可运行示例
const { Sequelize, DataTypes } = require('sequelize');
const sequelize = new Sequelize({
dialect: 'sqlite',
storage: 'tmp.sqlite',
});
(async () => {
const IntegerNames = sequelize.define('IntegerNames', {
value: { type: DataTypes.INTEGER, },
name: { type: DataTypes.STRING, },
}, {});
//await IntegerNames.sync({force: true})
await IntegerNames.create({value: 2, name: 'two'});
await sequelize.close();
})();
设置:
npm install sequelize@6.5.1 sqlite3@5.0.2.
在标准输出上我们可以看到它所做的查询:
Executing (default): DROP TABLE IF EXISTS `IntegerNames`;
Executing (default): CREATE TABLE IF NOT EXISTS `IntegerNames` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `value` INTEGER, `name` VARCHAR(255), `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL);
Executing (default): PRAGMA INDEX_LIST(`IntegerNames`)
Executing (default): INSERT INTO `IntegerNames` (`id`,`value`,`name`,`createdAt`,`updatedAt`) VALUES (NULL,$1,$2,$3,$4);
如果我们改用 force: false
,我们会得到相同的结果,只是开头没有 DROP
:
Executing (default): CREATE TABLE IF NOT EXISTS `IntegerNames` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `value` INTEGER, `name` VARCHAR(255), `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL);
Executing (default): PRAGMA INDEX_LIST(`IntegerNames`)
Executing (default): INSERT INTO `IntegerNames` (`id`,`value`,`name`,`createdAt`,`updatedAt`) VALUES (NULL,$1,$2,$3,$4);
如果我们删除同步,则根本不会创建表:
Executing (default): INSERT INTO `IntegerNames` (`id`,`value`,`name`,`createdAt`,`updatedAt`) VALUES (NULL,$1,$2,$3,$4);
测试:
npm install sequelize@6.5.1 sqlite3@5.0.2.
force: false
单独不同步架构,您需要 alter: true
使用 force: true
,数据库会被删除并重新创建,因此它当然匹配最新的架构,但您会丢失所有数据。
为了保留现有数据并更新架构,除了 alter: true
之外,我们还必须使用 force: false
。
以下工作和标准输出显示了用于通过创建临时数据库 IntegerNames_backup
使其工作的复杂查询序列:
const assert = require('assert')
const { Sequelize, DataTypes } = require('sequelize');
(async () => {
{
const sequelize = new Sequelize({
dialect: 'sqlite',
storage: 'tmp.sqlite',
});
const IntegerNames = sequelize.define('IntegerNames', {
value: { type: DataTypes.INTEGER, },
name: { type: DataTypes.STRING, },
}, {});
await IntegerNames.sync({force: true})
await IntegerNames.create({value: 2, name: 'two'});
await IntegerNames.create({value: 3, name: 'three'});
await sequelize.close();
}
// Alter by adding column..
{
const sequelize = new Sequelize({
dialect: 'sqlite',
storage: 'tmp.sqlite',
});
const IntegerNames = sequelize.define('IntegerNames', {
value: { type: DataTypes.INTEGER, },
name: { type: DataTypes.STRING, },
nameEs: { type: DataTypes.STRING, },
}, {});
await IntegerNames.sync({
alter: true,
force: false,
})
await IntegerNames.create({value: 5, name: 'five' , nameEs: 'cinco'});
await IntegerNames.create({value: 7, name: 'seven', nameEs: 'siete'});
const integerNames = await IntegerNames.findAll({
order: [['value', 'ASC']],
});
assert(integerNames[0].value === 2);
assert(integerNames[0].name === 'two');
assert(integerNames[0].nameEs === null);
assert(integerNames[1].name === 'three');
assert(integerNames[1].nameEs === null);
assert(integerNames[2].name === 'five');
assert(integerNames[2].nameEs === 'cinco');
assert(integerNames[3].name === 'seven');
assert(integerNames[3].nameEs === 'siete');
await sequelize.close();
}
})();
如果我们删除 alter: true
它会爆炸,因为新列不存在:
SequelizeDatabaseError: SQLITE_ERROR: table IntegerNames has no column named nameEs
迁移往往是推荐的方式,但在实际项目中更新架构:Sequelize: Changing model schema on production