
SQL to ORM Model Generator
Paste a CREATE TABLE SQL statement to generate an ORM model for Sequelize, GORM, SQLAlchemy, or Prisma. 100% client-side.
Last reviewed: April 2026New to this tool? Click here for instructions
How to Use the SQL to ORM Generator
To use the SQL to ORM Model Generator, follow these steps:
1. Paste your CREATE TABLE SQL statement into the left panel. The tool supports PostgreSQL, MySQL, SQLite, and SQL Server syntax.
2. Select the ORM you want to generate the model for from the dropdown menu. Options include Sequelize (JavaScript/Node.js), GORM (Go), SQLAlchemy (Python), and Prisma.
3. Click the 'Generate' button to create the ORM model.
4. Copy or download the generated model and paste it into your project.
When to Use the SQL to ORM Generator
Use the SQL to ORM Generator when you need to quickly convert existing SQL tables into ORM models for your application. This is particularly useful for developers who are new to ORMs or want to streamline their development process.
How It Works
The SQL to ORM Generator uses a client-side tool to parse your SQL statement and generate the corresponding ORM model. The tool supports multiple ORMs, including Sequelize, GORM, SQLAlchemy, and Prisma, allowing you to choose the one that best fits your project.
Tips, Edge Cases, and Limitations
Always review the generated ORM model to ensure it meets your requirements. The tool is designed to handle most common SQL table structures, but complex or unusual schemas may require manual adjustments.
The tool does not support advanced features like database migrations or complex relationships. For these features, consider using the full ORM library.
Frequently Asked Questions
Paste a CREATE TABLE statement and instantly get a ready-to-use ORM model for Sequelize, GORM, SQLAlchemy, Prisma, or TypeORM. The tool handles type mapping, null semantics, foreign key relations, auto-increment columns, and DEFAULT values โ all five ORM emitters run entirely in your browser with no server upload required.
What This Tool Does
This generator converts raw CREATE TABLE SQL statements into syntactically valid ORM model files for five frameworks: Sequelize (v6), GORM (v2), SQLAlchemy (2.0), Prisma (schema language v5), and TypeORM. Drop in one or many DDL statements, select your target ORM and SQL dialect, and receive model code you can paste directly into your project โ no manual type-lookup required.
From DDL to model in one click
The tool tokenizes your SQL, builds an abstract syntax tree, and walks it through an ORM-specific emitter. The result is idiomatic code for each framework: Prisma's schema language blocks, GORM struct tags, SQLAlchemy's DeclarativeBase with mapped_column, Sequelize's model.define style, or TypeORM's decorator-based entity class. Output has been tested against each ORM's runtime to confirm it parses without errors.
Supported input formats
PostgreSQL 15+, MySQL 8.0+, and SQLite 3.40+ dialects are all recognized. Paste a single table or a full schema dump with multiple statements separated by semicolons. Every TABLE node in the batch is processed in one pass, with cross-table foreign key references resolved across the entire input.
How to Use It: Step-by-Step with Worked Example
Paste your SQL
Open the SQL input pane on the left and paste your CREATE TABLE statement. To follow along with the example below, click the Try Example button โ it loads the users and comments tables automatically so you can see both a self-contained table and a table with a foreign key relationship.
Select your ORM and dialect
Use the ORM dropdown to choose Sequelize, GORM, SQLAlchemy, Prisma, or TypeORM. Then choose the SQL dialect that matches your schema's origin โ PostgreSQL, MySQL, or SQLite. Dialect selection affects how types like SERIAL (PostgreSQL) versus AUTO_INCREMENT (MySQL) and TINYINT(1) (MySQL's boolean representation) are normalized before emission. You can switch ORM targets at any time without re-pasting; the parser caches the AST.
Read the generated model
The output pane on the right updates immediately. Scan for any // UNKNOWN TYPE comments, which flag custom or domain types the tool couldn't map automatically. Everything else should be drop-in ready. SERIAL maps to @default(autoincrement()) in Prisma and to autoIncrement: true in other dialects.
Copy or download the output
Click Copy to push the generated code to your clipboard, or Download to save the file. The download filename derives from the detected table names (e.g. users.prisma, models.py). Related tool windows open in a new tab so your generated output stays in place.
Worked example: users + comments tables
Inputs
- Table 1 โ users
-
CREATE TABLE users ( id SERIAL PRIMARY KEY, email VARCHAR(255) NOT NULL UNIQUE, username VARCHAR(100), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, is_active BOOLEAN DEFAULT true, birth_date DATE ); - Table 2 โ comments
-
CREATE TABLE comments ( id SERIAL PRIMARY KEY, user_id INT NOT NULL REFERENCES users(id) ON DELETE CASCADE, body TEXT, posted_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP );
Step-by-step walkthrough
- Paste both CREATE TABLE statements into the SQL input pane, or click Try Example to auto-load them.
- Select Prisma from the ORM dropdown and PostgreSQL as the dialect.
- Click Generate. The tool tokenizes the DDL, builds an AST with two TABLE nodes and one REFERENCE node, then runs the Prisma emitter.
- Inspect the output:
SERIALmaps toInt @id @default(autoincrement());VARCHAR(255) NOT NULL UNIQUEmaps toString @unique; the nullableVARCHAR(100)becomesString?;TIMESTAMP DEFAULT CURRENT_TIMESTAMPmaps toDateTime @default(now()). - Verify the relation:
user_id INT NOT NULL REFERENCES users(id) ON DELETE CASCADEbecomes auserId Intfield plus aUser @relation(fields: [userId], references: [id], onDelete: Cascade)block on the Comment model. - Switch the ORM dropdown to Sequelize without re-pasting โ the tool re-emits from the cached AST. Confirm
DataTypes.STRING(255),allowNull: false, andunique: trueappear on theemailcolumn, anddefaultValue: DataTypes.NOWappears oncreated_at. - Click Copy to push the output to clipboard, or Download to save as
users.prisma.
Expected output โ Prisma
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model User {
id Int @id @default(autoincrement())
email String @unique
username String?
createdAt DateTime @default(now())
isActive Boolean @default(true)
birthDate DateTime? @db.Date
comments Comment[]
}
model Comment {
id Int @id @default(autoincrement())
userId Int
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
body String?
postedAt DateTime @default(now())
}
Same tables as Sequelize (Node.js)
const { DataTypes } = require('sequelize');
module.exports = (sequelize) => {
const User = sequelize.define('User', {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
email: {
type: DataTypes.STRING(255),
allowNull: false,
unique: true,
},
username: {
type: DataTypes.STRING(100),
allowNull: true,
},
createdAt: {
type: DataTypes.DATE,
defaultValue: DataTypes.NOW,
},
isActive: {
type: DataTypes.BOOLEAN,
defaultValue: true,
},
birthDate: {
type: DataTypes.DATEONLY,
allowNull: true,
},
});
const Comment = sequelize.define('Comment', {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
userId: {
type: DataTypes.INTEGER,
allowNull: false,
},
body: {
type: DataTypes.TEXT,
allowNull: true,
},
postedAt: {
type: DataTypes.DATE,
defaultValue: DataTypes.NOW,
},
});
// Associations โ add to your model setup file:
// User.hasMany(Comment, { foreignKey: 'userId', onDelete: 'CASCADE' });
// Comment.belongsTo(User, { foreignKey: 'userId' });
return { User, Comment };
};
Supported ORM Frameworks and SQL Dialects
Sequelize (Node.js)
Output targets Sequelize v6 using the sequelize.define() model style. Column definitions use DataTypes.* constants as documented at sequelize.org. Association stubs for hasMany / belongsTo are generated as comments alongside the foreign key column so you can move them into your model setup file.
GORM (Go)
GORM v2 structs are emitted with gorm:"..." struct tags, following the conventions at gorm.io. Nullable columns are represented as pointer types (*string, *bool) so Go's zero-value doesn't ambiguously represent a stored NULL.
SQLAlchemy (Python)
Generated code uses the SQLAlchemy 2.0 unified API: a DeclarativeBase subclass with mapped_column() calls. Type references follow the SQLAlchemy type system documentation. The 2.0 API is used rather than the legacy 1.x Column() style to keep output current with active codebases.
Prisma (TypeScript/JavaScript)
Output is Prisma Schema Language (PSL) including a datasource db block and a generator client block, per the Prisma schema reference. Prisma is schema-first: commit the .prisma file and run prisma migrate dev to synchronize the database.
TypeORM (TypeScript)
Entities use the @Entity(), @Column(), and @PrimaryGeneratedColumn() decorator syntax per the TypeORM TypeScript decorators guide. Each column decorator receives an options object with nullable, unique, default, and type keys.
SQL dialect support: PostgreSQL, MySQL, SQLite
PostgreSQL-specific types like SERIAL, TEXT, and BOOLEAN differ from their MySQL equivalents. MySQL uses AUTO_INCREMENT for sequences and TINYINT(1) as its canonical boolean โ the dialect normalization layer converts both to an internal BOOL node before any ORM emitter sees the AST. SQLite's looser type affinity system is handled by mapping declared type names to the nearest SQL-92 equivalent.
Type Mapping: How SQL Columns Become ORM Properties
The table below is the authoritative cross-reference for this tool's type mapping. SQL base types are defined per ISO/IEC 9075 (SQL-92); ORM types are taken directly from each framework's official documentation.
Primitive types
INT maps across all five ORMs as: DataTypes.INTEGER in Sequelize, a bare int field in GORM, Integer in SQLAlchemy, Int in Prisma, and int / number in TypeORM. BIGINT follows the same pattern one size up. VARCHAR(n) carries its length parameter through: DataTypes.STRING(255) in Sequelize, String with a size:255 gorm tag in GORM, String(255) in SQLAlchemy, and String in Prisma (length constraints live in the database layer via @db.VarChar(255)).
Date and time types
TIMESTAMP maps to DataTypes.DATE in Sequelize (which stores with timezone), time.Time in GORM, DateTime in SQLAlchemy 2.0, DateTime in Prisma, and Date in TypeORM. DATE (date-only) maps to DataTypes.DATEONLY in Sequelize and DateTime @db.Date in Prisma.
Special types: BOOLEAN, JSON, UUID
BOOLEAN maps to DataTypes.BOOLEAN / bool / Boolean / Boolean / boolean across the five ORMs respectively. UUID requires slightly more care: Sequelize uses DataTypes.UUID, GORM uses uuid.UUID from the github.com/google/uuid package, SQLAlchemy uses UUID() from sqlalchemy.dialects.postgresql, Prisma uses String @db.Uuid, and TypeORM uses uuid as the column type string.
Precision types: DECIMAL and NUMERIC
DECIMAL(10,2) maps to DataTypes.DECIMAL(10,2) in Sequelize, float64 in GORM (with an optional type:decimal(10,2) tag for migration accuracy), Numeric(10, 2) in SQLAlchemy, Decimal in Prisma, and decimal with precision: 10, scale: 2 in TypeORM.
| SQL Type | Sequelize | GORM | SQLAlchemy 2.0 | Prisma | TypeORM |
|---|---|---|---|---|---|
| INT | DataTypes.INTEGER | int | Integer | Int | int |
| BIGINT | DataTypes.BIGINT | int64 | BigInteger | BigInt | bigint |
| VARCHAR(n) | DataTypes.STRING(n) | string `gorm:"size:n"` | String(n) | String | varchar |
| TEXT | DataTypes.TEXT | string `gorm:"type:text"` | Text | String | text |
| BOOLEAN | DataTypes.BOOLEAN | bool | Boolean | Boolean | boolean |
| DATE | DataTypes.DATEONLY | time.Time | Date | DateTime @db.Date | date |
| TIMESTAMP | DataTypes.DATE | time.Time | DateTime | DateTime | timestamp |
| DECIMAL(p,s) | DataTypes.DECIMAL(p,s) | float64 | Numeric(p, s) | Decimal | decimal |
| FLOAT | DataTypes.FLOAT | float32 | Float | Float | float |
| UUID | DataTypes.UUID | uuid.UUID | UUID() | String @db.Uuid | uuid |
| JSON | DataTypes.JSON | datatypes.JSON | JSON | Json | json |
*string) are used for nullable columns โ see the Edge Cases section below.Edge Cases: Constraints, Indexes, Foreign Keys, and Defaults
Type mapping is the straightforward part. The constraint layer is where naive substitution scripts break down โ and where the AST-based approach earns its keep.
UNIQUE constraints and unique indexes
A single-column UNIQUE constraint maps to the ORM's per-column unique flag: unique: true in Sequelize, a uniqueIndex gorm tag in GORM, UniqueConstraint in SQLAlchemy, and @unique in Prisma. Multi-column UNIQUE constraints โ declared at the table level as UNIQUE(col1, col2) โ map to an indexes array entry in Sequelize, a composite uniqueIndex tag across fields in GORM, UniqueConstraint(col1, col2) in SQLAlchemy, and a @@unique([col1, col2]) block attribute in Prisma.
NOT NULL vs nullable
Any column without an explicit NOT NULL is treated as nullable. The tool emits allowNull: true in Sequelize (even though it's the framework default โ explicit beats implicit), a pointer type like *string or *bool in GORM so Go's nil represents stored NULL rather than a zero value, nullable=True in SQLAlchemy, and a ? suffix on the Prisma type (String?). TypeORM columns receive nullable: true in the @Column() decorator.
Foreign key ON DELETE / ON UPDATE actions
The REFERENCES users(id) ON DELETE CASCADE clause from the worked example propagates to each ORM: Sequelize association stubs receive onDelete: 'CASCADE'; GORM gets a constraint:OnDeleteCascade tag; SQLAlchemy uses cascade='all, delete-orphan' on the relationship; Prisma generates onDelete: Cascade inside the @relation block; TypeORM uses onDelete: 'CASCADE' in the @ManyToOne decorator options. ON UPDATE actions follow the same per-ORM pattern.
Composite primary keys
Multiple columns carrying the PRIMARY KEY flag, or a table-level PRIMARY KEY(col1, col2) constraint, produces the correct multi-column primary key syntax for each ORM: @@id([col1, col2]) in Prisma, PrimaryKeyConstraint('col1', 'col2') in SQLAlchemy's __table_args__, gorm:"primaryKey" on each participating field in GORM, and primaryKey: true on each column definition in Sequelize.
CHECK constraints
CHECK constraint expressions (e.g. CHECK (age >= 18)) are emitted as a comment block with a warning that most ORMs do not enforce CHECK logic at the model layer. The original SQL expression is preserved in the comment so you can add equivalent application-level validation. The Regex Tester can help validate that logic before you port it.
DEFAULT values including CURRENT_TIMESTAMP
CURRENT_TIMESTAMP and NOW() defaults map to @default(now()) in Prisma, defaultValue: DataTypes.NOW in Sequelize, server_default=func.now() in SQLAlchemy, autoCreateTime in GORM (on a time.Time field tagged gorm:"autoCreateTime"), and default: () => 'CURRENT_TIMESTAMP' in TypeORM. Static string defaults like DEFAULT 'pending' are emitted as literal string defaults in each ORM's syntax.
SERIAL / AUTO_INCREMENT / AUTOINCREMENT across dialects
PostgreSQL's SERIAL pseudo-type expands internally to INTEGER NOT NULL DEFAULT nextval('seq'). The dialect normalization layer detects this and marks the column as autoIncrement before any emitter runs. MySQL's AUTO_INCREMENT and SQLite's AUTOINCREMENT keyword are normalized identically. The result: @default(autoincrement()) in Prisma, autoIncrement: true in Sequelize and TypeORM, autoincrement=True in SQLAlchemy, and gorm:"autoIncrement" in GORM.
Behind the Scenes: SQL Parsing and Code Generation
The generator uses a genuine multi-stage parsing pipeline, not a find-and-replace script. Understanding the pipeline explains both what the tool handles well and where you might need to intervene.
Lexing and tokenizing the DDL
A hand-rolled lexer handles SQL-92 base syntax (ISO/IEC 9075) plus the extensions specific to PostgreSQL 15, MySQL 8.0, and SQLite 3.40. Keywords, identifiers, string literals, and punctuation are streamed as typed tokens. Quoted identifiers ("my column" in PostgreSQL, `my column` in MySQL) are preserved and sanitized to valid identifier strings in the target ORM language.
AST construction
The token stream feeds a recursive descent parser that produces AST nodes representing TABLE, COLUMN, CONSTRAINT, INDEX, and REFERENCE entities. Each COLUMN node carries its type, length/precision arguments, nullability, default expression, and any inline constraints. REFERENCE nodes are resolved across the full input batch, so cross-table relations are linked even when the referenced table appears after the referencing one.
ORM-specific code emitters
Each of the five ORMs has a dedicated emitter โ a visitor that walks the AST and constructs a code string using that ORM's idioms. Emitters do not use string templates; they call typed builder functions so structural errors (e.g. a missing closing brace in TypeScript) are impossible by construction. No user input leaves the browser: the entire pipeline โ lexer, parser, and all five emitters โ runs as a compiled WebAssembly module.
Dialect normalization layer
Before any emitter sees the AST, a normalization pass converts dialect-specific constructs to canonical internal types. TINYINT(1) in MySQL input is normalized to BOOL; SERIAL in PostgreSQL becomes INTEGER + autoIncrement; SQLite's INTEGER PRIMARY KEY convention (which implies ROWID aliasing) is normalized to an autoIncrement primary key. All five ORM emitters therefore consume a consistent, dialect-agnostic AST regardless of which SQL flavor you pasted.
Choosing the Right ORM for Your Stack
If you're still evaluating frameworks rather than converting an existing schema, the feature matrix below summarizes the practical tradeoffs. The right choice almost always follows from your language, team size, and whether you prefer a schema-first or code-first workflow.
When to choose Sequelize
Sequelize suits teams already in the Node.js ecosystem who want a battle-tested library with a large plugin surface. If your codebase predates Prisma's mainstream adoption (roughly 2021+), Sequelize v6 is likely already present. It supports raw SQL escapes, custom hooks, and all major relational databases.
When to choose GORM
GORM is the idiomatic Go choice โ struct tags, no meaningful competitors at the same adoption level in the Go ecosystem. The gorm.io documentation is comprehensive, and the library integrates with golang-migrate for schema versioning. Go's static typing makes the pointer-for-nullable pattern safe and explicit.
When to choose SQLAlchemy
SQLAlchemy 2.0's unified Core + ORM API provides the most flexible raw-SQL escape hatch of the five options. The text() construct lets you drop into raw SQL without abandoning the session or connection pool. For Python shops using Alembic for migrations, SQLAlchemy is the natural anchor of the data layer.
When to choose Prisma
Prisma's schema-first approach โ commit a .prisma file, run prisma migrate dev โ appeals to teams who want the database schema to be the single source of truth. The generated client is fully typed with no additional configuration, making it particularly well-suited to TypeScript monorepos. Use the JSON Formatter to inspect the JSON payloads Prisma's client returns from findMany calls during development.
When to choose TypeORM
TypeORM's decorator-based entity syntax matches TypeScript class idioms more closely than Sequelize's define() style, which makes it a natural fit for NestJS or other decorator-heavy frameworks. The @PrimaryGeneratedColumn() and @ManyToOne() decorators are self-documenting at a glance.
| ORM | Language | TypeScript | Migration Tool | Relation Support | Query Builder | Schema-First | Code-First |
|---|---|---|---|---|---|---|---|
| Sequelize | JavaScript / Node.js | Partial (types pkg) | sequelize-cli | Yes | Yes | No | Yes |
| GORM | Go | No | golang-migrate | Yes | Yes | No | Yes |
| SQLAlchemy | Python | No | Alembic | Yes | Yes (Core) | No | Yes |
| Prisma | TypeScript / JavaScript | Yes (native) | prisma migrate | Yes | Yes (Client) | Yes | No |
| TypeORM | TypeScript / JavaScript | Yes (native) | typeorm migration | Yes | Yes | No | Yes |
Related Tools
Before pasting into this generator, run messy or minified SQL through the SQL Beautifier โ format your DDL before converting to catch syntax errors early. Once your models are generated, use the JSON Formatter โ inspect and validate JSON column payloads to verify what your ORM returns at runtime. All related tools open in a new tab so your generated model output stays in place.