Create knex.js migration for existing database. Input Database structure in the form of create table SQL statements, and this ejs template can create Knex.js migration
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<% | |
const Parser = require('sql-ddl-to-json-schema'); | |
const fs = require('fs'); | |
const [ sqlFileName ] = argv; | |
if( !sqlFileName ) throw new Error('SQL file not specified'); | |
const parser = new Parser('mysql'); | |
parser.feed( fs.readFileSync( sqlFileName, 'utf-8')); | |
const data = parser.toCompactJson(); | |
// const data = parser.toJsonSchemaArray(); | |
// const util = require('util'); | |
// console.log( util.inspect( data, { depth: null })); | |
// process.exit(); | |
// console.log( JSON.stringify( data )); | |
// data = JSON.parse( dataStr ); | |
var typemap = { | |
int: 'integer', | |
text: 'text', | |
varchar: 'string', | |
timestamp: 'timestamp', | |
datetime: 'datetime', | |
enum: 'enum' | |
}; | |
function getType( col ){ | |
if( col.options.autoincrement ){ | |
return 'increments'; | |
} | |
const out = typemap[col.type.datatype]; | |
if( out === undefined ){ throw 'Unknown column: ' + col.type.datatype } | |
return out; | |
} | |
function getLen( col ){ | |
var out; | |
var t = col.type; | |
switch( t.datatype ){ | |
case 'int': | |
out = t.width; | |
break; | |
case 'varchar': | |
out = t.length; | |
break; | |
case 'enum': | |
out = "['" + t.values.join("','") + "']"; | |
break; | |
} | |
if( out !== undefined ){ | |
return ', ' + out; | |
} | |
return '' | |
} | |
var timestampCols = ['timestamp', 'datetime']; | |
function getDefVal(col){ | |
if( ( timestampCols.indexOf(col.type.datatype) !== -1) && col.options.default === 'current_timestamp()'){ | |
return 'knex.fn.now()'; | |
} | |
return `'${col.options.default}'`; | |
} | |
function getFkCols( cols ){ | |
return cols.map( v => v.column ).toString(); | |
} | |
function capitalize( str ){ | |
return str.charAt(0).toUpperCase() + str.slice(1); | |
} | |
%> | |
exports.up = async function(knex) { | |
<% data.forEach( function( tbl ){ %> | |
await knex.schema.createTable('<%-tbl.name -%>', function(table) { | |
/* Column defnitions */ | |
<% tbl.columns.forEach( function( col ){ -%> | |
table.<%-getType( col )-%>('<%- col.name -%>'<%- getLen(col); _%>) | |
<%_ if(col.options.autoincrement){ _%> | |
.primary() | |
<%_}_%> | |
<%_ if(col.options.unsigned){ _%> | |
.unsigned() | |
<%_}_%> | |
<%_ if(col.options.nullable === false ){ _%> | |
.notNullable() | |
<%_}_%> | |
<%_ if( [undefined,null].indexOf(col.options.default) === -1 ){ _%> | |
.defaultTo(<%- getDefVal( col ) -%>) | |
<%_}_%> | |
<% }) %> | |
/* Column defnitions */ | |
<% if(tbl.foreignKeys) {%> | |
/* Foreign key defnitions */ | |
<% tbl.foreignKeys.forEach( function( fk ){ -%> | |
table.foreign('<%- getFkCols(fk.columns) -%>') | |
.references('<%- getFkCols(fk.reference.columns ) -%>') | |
<% fk.reference.on && fk.reference.on.forEach( function( on ){ -%> | |
.on<%- capitalize(on.trigger) -%>('<%- on.action -%>') | |
<% }) -%> | |
.inTable('<%-fk.reference.table-%>'); | |
<% }) %> | |
/* Foreign key defnitions */ | |
<%}%> | |
<% if(tbl.uniqueKeys) {%> | |
/* Unique key indexes */ | |
<% tbl.uniqueKeys.forEach( function( uk ){ -%> | |
table.unique('<%- getFkCols(uk.columns) -%>'); | |
<% }) %> | |
/* Unique key indexes */ | |
<%}%> | |
}); | |
<% })%> | |
}; | |
exports.down = async function(knex) { | |
await knex.schema | |
<% data.reverse().forEach( function( tbl ){ _%> | |
.dropTable('<%- tbl.name -%>') | |
<% }) _%> | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment