SQL to Sequelize Model
Generate a Sequelize model from a SQL CREATE TABLE statement.
Related Tools
Generate a Prisma schema model from a SQL CREATE TABLE statement.
Generate a TypeORM entity class from a SQL CREATE TABLE statement.
Generate a Drizzle ORM schema from a SQL CREATE TABLE statement.
Convert CSV rows into SQL INSERT statements.
Generate TypeScript interfaces or type aliases from JSON.
Generate a SQLAlchemy declarative model from a SQL CREATE TABLE statement.
Documentation
What is SQL to Sequelize?
SQL to Sequelize converts CREATE TABLE statements into Sequelize v6 model definitions — one sequelize.define() call per table, exported as a factory function, the pattern most existing Sequelize codebases already use.
How it works
Each table becomes module.exports.define<Model> = (sequelize) => { ... }, wrapping a call to sequelize.define('ModelName', { fields }, { tableName, timestamps: false }). Note the field keys keep the original SQL column names (snake_case), unlike the Prisma/Drizzle/TypeORM generators, which camelCase them — Sequelize's object-based config style maps more naturally onto the raw column name. Types go through a dedicated table: INTEGER/SERIAL → DataTypes.INTEGER, VARCHAR(n) → DataTypes.STRING(n), TIMESTAMP → DataTypes.DATE, UUID → DataTypes.UUID. tableName is always set explicitly to the real SQL table name (Sequelize would otherwise guess a pluralized, camelCased name from the model), and timestamps: false is always set so Sequelize doesn't silently expect createdAt/updatedAt columns your table may not have. As with the other generators, only literal defaults and CURRENT_TIMESTAMP (→ defaultValue: DataTypes.NOW) are translated.
Features
- One exported
define<Model>(sequelize)factory function per table - Explicit
tableNameandtimestamps: falseso the model matches your real schema exactly - Type-aware field options:
primaryKey,autoIncrement,allowNull,unique - Literal and
NOWdefaults translated; everything else left as a comment - Copy or download the generated
.jsmodel file
Example
Input:
CREATE TABLE users ( id SERIAL PRIMARY KEY, external_id UUID DEFAULT uuid_generate_v4(), name VARCHAR(255) NOT NULL, is_active BOOLEAN DEFAULT true ); CREATE TABLE posts ( id SERIAL PRIMARY KEY, user_id INTEGER NOT NULL REFERENCES users(id), title VARCHAR(255) NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP );
Output:
const { DataTypes } = require('sequelize');
module.exports.defineUser = (sequelize) => {
const User = sequelize.define('User', {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
external_id: {
type: DataTypes.UUID,
}, // SQL default not translated: uuid_generate_v4()
name: {
type: DataTypes.STRING(255),
allowNull: false,
},
is_active: {
type: DataTypes.BOOLEAN,
defaultValue: true,
},
}, {
tableName: 'users',
timestamps: false,
});
return User;
};
module.exports.definePost = (sequelize) => {
const Post = sequelize.define('Post', {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
user_id: {
type: DataTypes.INTEGER,
allowNull: false,
}, // FK -> users.id
title: {
type: DataTypes.STRING(255),
allowNull: false,
},
created_at: {
type: DataTypes.DATE,
defaultValue: DataTypes.NOW,
},
}, {
tableName: 'posts',
timestamps: false,
});
return Post;
};Common errors
A DEFAULT the generator can't confidently translate — like uuid_generate_v4() above — is never invented as a fake defaultValue; it's left as // SQL default not translated: uuid_generate_v4() next to the field so you add the real behavior (often defaultValue: () => crypto.randomUUID() or a DB-side default) yourself. Foreign keys appear only as // FK -> table.column comments on a plain integer field — Sequelize associations (belongsTo, hasMany) are declared separately once both models are defined, and require you to decide the association alias, so they're intentionally not generated.
Best practices
Call each exported define<Model> function with your initialized Sequelize instance during app startup, then add associations (Post.belongsTo(User, { foreignKey: 'user_id' })) right after, using the FK comments as your checklist. Search the output for both comment markers before treating it as production-ready.
Frequently Asked Questions
Why sequelize.define() instead of the newer class-based Model.init()?▾
sequelize.define() is still the most widely used and documented pattern across existing Sequelize (v6) codebases, and it doesn't require setting up a class hierarchy — you get a working model from one function call. If your project uses the class-based style, the field definitions translate directly into the second argument of Model.init().
Why does the output set tableName and timestamps: false explicitly?▾
Without tableName, Sequelize pluralizes and camelCases the model name into a guessed table name — which won't match your actual SQL table unless you're following Sequelize's own naming convention already. timestamps: false turns off Sequelize's automatic createdAt/updatedAt columns, since the DDL doesn't necessarily have those and adding them silently would create columns that don't exist in your real table.
Are foreign keys wired up with associations (belongsTo, etc.)?▾
No — a foreign key column becomes a plain integer field with a comment noting what it references. Sequelize associations are defined separately (via Model.belongsTo(...)) after both models exist, and naming/aliasing that association is a judgment call the DDL alone doesn't answer.
How is DEFAULT CURRENT_TIMESTAMP handled?▾
As defaultValue: DataTypes.NOW, Sequelize's built-in way to set the current timestamp as a column default. Other SQL default expressions aren't guessed at — only literal values and this common case are translated, with anything else flagged in a comment.