Зачем секвенировать вопросы "показать индекс из таблицы"?
Если бы вы включили ведение журнала Sequelize
, вы бы увидели, что во время фазы "синхронизация" и сразу после создания таблицы Sequelize
выполняет запрос SHOW INDEX FROM table
. Вопрос в том-почему?
Чтобы быть более конкретным, вот код, который я выполняю:
var Sequelize = require('sequelize');
var connection = new Sequelize('demo_schema', 'root', 'password');
var Article = connection.define('article', {
slug: {
type: Sequelize.STRING,
primaryKey: true
},
title: {
type: Sequelize.STRING,
unique: true,
allowNull: false
},
body: {
type: Sequelize.TEXT
}
}, {
timestamps: false
});
connection.sync({
force: true,
logging: console.log
}).then(function () {
// TODO
});
Вот вывод на консоль:
Executing (default): DROP TABLE IF EXISTS `articles`;
Executing (default): DROP TABLE IF EXISTS `articles`;
Executing (default): CREATE TABLE IF NOT EXISTS `articles` (`slug` VARCHAR(255) , `title` VARCHAR(255) NOT NULL UNIQUE, `body` TEXT, UNIQUE `articles_title_unique` (`title`), PRIMARY KEY (`slug`)) ENGINE=InnoDB;
Executing (default): SHOW INDEX FROM `articles`
1 ответ:
Причина, по которой Sequelize использует
SHOW INDEX FROM
, заключается в том, чтобы избежать повторного добавления существующих индексов в таблицу модели. Добавление существующего индекса во второй раз приведет к ошибке.Sequelize в настоящее время недостаточно" умна", чтобы понять, что вы не определили никаких индексов. Он все равно проверяет таблицу.
В вашем сценарии это не имеет значения, так как вы принудительно синхронизируете. Это означает, что таблицы всегда удаляются и создаются заново. При добавлении новых индексов их не будет существующий индекс.
Представьте, что вы задали бы модель с индексами так:
Развернутую форму этого примера можно найти в http://docs.sequelizejs.com/en/latest/docs/models-definition/#indexes .sequelize.define('user', {}, { indexes: [ // Create a unique index on email { unique: true, fields: ['email'] } ] })
Вымышленная История
Если вы создали таблицу с Sequelize.sync () вчера добавил новый индекс в вашу модель сегодня и не будет использовать принудительную синхронизацию (потому что тогда таблица будет удалена и создана -- > нет существующие индексы), Sequelize добавит только новый индекс.
Как здесь работает Sequelize?
Sequelize определяет, какие индексы являются новыми, выдавая
SHOW INDEX FROM
и сравнивая возвращаемое значение с индексами вашей модели. Если Sequelize обнаружит, что в вашей модели больше (или больше) индексов, чем в существующей таблице, он добавит эти индексы в базовую таблицу.Код, делающий это, можно найти наGitHub . В следующем фрагменте кода я добавлены некоторые комментарии к соответствующему коду:
// this.QueryInterface.showIndex produces the statement `SHOW INDEX FROM [table of the model]`. It returns a promise containing the found indexes. .then(() => this.QueryInterface.showIndex(this.getTableName(options), options)) // `indexes` will contain the indexes which are present on the existing table. // If you force sync, this will always be empty since the table is new. .then(indexes => { // Assign an auto-generated name to indexes which are not named by the user this.options.indexes = this.QueryInterface.nameIndexes(this.options.indexes, this.tableName); // Fill `indexes` with only the indexes from your model which are not present on the table. indexes = _.filter(this.options.indexes, item1 => !_.some(indexes, item2 => item1.name === item2.name)); // .map iterates over `indexes` and adds an index for each entry. // Remeber, this is for indexes which are present in the model definition but not present on the table. return Promise.map(indexes, index => this.QueryInterface.addIndex( this.getTableName(options), _.assign({ logging: options.logging, benchmark: options.benchmark, transaction: options.transaction }, index), this.tableName )); })