Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save francolaiuppa/56c247daf72e0efdf80b05411572c70e to your computer and use it in GitHub Desktop.
Save francolaiuppa/56c247daf72e0efdf80b05411572c70e to your computer and use it in GitHub Desktop.
Automatically generates migration files from your sequelize models
'use strict';
//////////////////////////////////
// How to use?
// 1. Create `sequelize-schema-file-generator.js` in your app root
// 2. Make sure you've ran the `sequelize init` before (It should create `config`,`seeders`,`migrations` folders).
// 3. Update `DATABASE_DSN` below to match your connection string (works with any database adapter that Sequelize supports)
// 4. Run it with `node sequelize-schema-file-generator.js`
// 5. Review the generated migrations inside of the `migrations` folder.
//////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////// CHANGE THIS /////////////////////////////////////////////
const DATABASE_DSN = 'mysql://root@localhost/testing';
///////////////////////////////// END CHANGES /////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
/* jscs:disable */
var models = require('./models').sequelize.models;
var Sequelize = require('sequelize');
var fs = require('fs');
delete models.default;
const sequelize = new Sequelize(DATABASE_DSN);
for(let model in models) {
let attributes = models[model].attributes;
for(let column in attributes) {
delete attributes[column].Model;
delete attributes[column].fieldName;
delete attributes[column].field;
for(let property in attributes[column]) {
if(property.startsWith('_')) {
delete attributes[column][property];
}
}
if(typeof attributes[column]['type'] !== 'undefined') {
if(typeof attributes[column]['type']['options'] !== 'undefined' && typeof attributes[column]['type']['options'].toString === 'function') {
attributes[column]['type']['options'] = attributes[column]['type']['options'].toString(sequelize);
}
if(typeof attributes[column]['type'].toString === 'function') {
attributes[column]['type'] = attributes[column]['type'].toString(sequelize);
}
}
}
let schema = JSON.stringify(attributes, null, 4);
let tableName = models[model].tableName;
let indexes = ['\n'];
if(models[model].options.indexes.length) {
models[model].options.indexes.forEach((obj) => {
indexes.push(' .then(() => {');
indexes.push(' return queryInterface.addIndex(');
indexes.push(` '${tableName}',`);
indexes.push(` ['${obj.fields.join("','")}']`);
let opts = {};
if(obj.name) {
opts.indexName = obj.name;
}
if(obj.unique === true) {
opts.indicesType = 'UNIQUE';
}
if(obj.method === true) {
opts.indexType = obj.method;
}
if(Object.keys(opts).length) {
indexes.push(` , ${JSON.stringify(opts)}`)
}
indexes.push(' )');
indexes.push(' })');
});
}
schema = schema.split('\n').map((line) => ' ' + line).join('\n');
let template = `'use strict';
module.exports = {
up: function(queryInterface, Sequelize) {
return queryInterface.sequelize.query('SET FOREIGN_KEY_CHECKS = 0')
.then(() => {
return queryInterface.createTable('${tableName}',
${schema})
})${indexes.join('\n')}
.then(() => {
return queryInterface.sequelize.query('SET FOREIGN_KEY_CHECKS = 1');
});
},
down: function(queryInterface, Sequelize) {
return queryInterface.sequelize.query('SET FOREIGN_KEY_CHECKS = 0')
.then(() => {
return queryInterface.dropTable('${tableName}');
})
.then(() => {
return queryInterface.sequelize.query('SET FOREIGN_KEY_CHECKS = 1');
});
}
};`
let d = new Date();
let filename = [d.getFullYear(), d.getMonth()+1, d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds()]
.map((num) => num <= 60 && (num + 100).toString().substring(1) || num)
.join('') + `-${models[model].tableName}`;
fs.writeFileSync(`./migrations/${filename}.js`, template);
};
@ahelord
Copy link

ahelord commented Mar 28, 2017

have node 6.6.0 dont run this file

@ahelord
Copy link

ahelord commented Mar 28, 2017

have this error in node 6.6.0 throw new Error(this.name + '.' + Utils.lowercaseFirst(Type.toString()) + ' called with something that's not an instance of Sequelize.Model');

@pepijnmm
Copy link

node: v10.16.0
sequelize: ^5.7.0

got the error :
schema = schema.split('\n').map((line) => ' ' + line).join('\n');
^

TypeError: Cannot read property 'split' of undefined

changed line 28: let attributes = models[model].attributes;
to: let attributes = models[model].rawAttributes;
which fixed it for me

where was the FOREIGN_KEY_CHECKS for?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment