1. Home
  2. Developer tools
  3. SQL to Drizzle & TypeORM

SQL to Drizzle & TypeORM

Start a Drizzle or TypeORM project on top of a database you already have, without typing every column builder by hand.

Free, no sign-up. Runs in your browser: nothing is uploaded.

How to use SQL to Drizzle & TypeORM

  1. Paste CREATE TABLE statements.
  2. Pick Drizzle (PostgreSQL, MySQL or SQLite) or TypeORM.
  3. Copy the TypeScript into your schema file.

Features

  • pgTable, mysqlTable and sqliteTable with typed column builders
  • .notNull(), .default(), .defaultNow(), .unique() and .primaryKey()
  • .references(() => table.id, { onDelete }) for foreign keys
  • pgEnum and mysqlEnum declarations
  • TypeORM @Entity, @Column, @PrimaryGeneratedColumn and @ManyToOne

Supported formats

You can open

  • SQL

You get

  • TS

Private by design

Your files are opened and processed by your browser on this device. They are never uploaded to openWorkstand or anyone else, so the SQL to Drizzle & TypeORM is safe for contracts, IDs, photos and work documents. After you have used it once while online, it also works without an internet connection. How local processing works

Good to know

  • Defaults that call database functions other than now() are left out; add them by hand with Drizzle’s sql helper.
  • CHECK constraints and views are skipped.

Guide

From SQL tables to a Drizzle schema or TypeORM entities

Drizzle ORM keeps its schema in TypeScript: each table is a call such as pgTable('users', {...}) with a typed builder for every column. That gives excellent type safety, but rewriting an existing database in that form by hand is tedious and error-prone. This converter reads CREATE TABLE statements and writes the Drizzle schema, or TypeORM entity classes if that is the ORM your project uses.

Three Drizzle dialects

Drizzle has a separate core package per database, and column builders differ between them. For PostgreSQL the output imports from drizzle-orm/pg-core and uses builders such as serial, varchar, numeric, timestamp with withTimezone, jsonb and uuid. For MySQL it uses mysql-core with int, varchar, decimal, datetime and mysqlEnum, adding .autoincrement() where the SQL had AUTO_INCREMENT. For SQLite it maps everything onto SQLite’s few storage classes: integers, real, text and blob, with booleans and timestamps stored as integers in boolean or timestamp mode.

Keys, defaults and constraints

Each column becomes a builder followed by a chain of modifiers. Single-column primary keys get .primaryKey(), NOT NULL becomes .notNull(), UNIQUE becomes .unique(), literal defaults become .default(...) and now() or CURRENT_TIMESTAMP becomes .defaultNow(). A composite primary key, as on a join table, is written in the table’s extra configuration with primaryKey({ columns: [...] }).

Foreign keys and enums

References become .references(() => users.id, { onDelete: 'cascade' }). The arrow function lets tables refer to each other regardless of the order they are declared in. PostgreSQL enums are declared once at the top with pgEnum('order_status', [...]) and then used like a column builder, which is how Drizzle creates the matching CREATE TYPE in migrations.

A worked example

From the Sample, the orders table becomes pgTable('orders', {...}) with id: bigserial('id', { mode: 'number' }).primaryKey(), userId: integer('user_id').notNull().references(() => users.id, { onDelete: 'cascade' }), status: orderStatusEnum('status').notNull().default("pending"), total: numeric('total', { precision: 10, scale: 2 }).notNull() and placedAt: timestamp('placed_at', { withTimezone: true }).notNull().defaultNow(). The enum itself appears above the tables as export const orderStatusEnum = pgEnum('order_status', ['pending', 'paid', 'shipped', 'cancelled']).

The TypeORM option

TypeORM describes tables as decorated classes instead. Each table becomes an @Entity({ name: 'orders' }) class, auto-increment keys become @PrimaryGeneratedColumn, other columns @Column with their SQL type, length, precision and nullability, and foreign keys a @ManyToOne property with @JoinColumn naming the column. This suits NestJS projects and codebases that already use TypeORM 0.3.

What to finish by hand

Drizzle’s relations() helpers, which power the relational query API, are not generated; they are short to write once the tables exist. Defaults that call database functions other than now(), CHECK constraints, views and triggers are skipped. Review numeric columns that hold money, since numeric values arrive in JavaScript as strings.

Picking Drizzle or TypeORM

Both ORMs can describe the same database, but they feel different in code. Drizzle keeps the schema as plain objects and writes queries that look like SQL, with types inferred straight from the table definitions, so there is no code generation step. TypeORM uses classes and decorators, has an Active Record or repository style, and is the default in many NestJS templates. If you are starting fresh in a TypeScript project, Drizzle’s output is shorter and easier to review; if the rest of the codebase already uses TypeORM entities, generate those so the new tables match the old ones.

Wiring it up

Save the Drizzle output as src/db/schema.ts, create the client with the driver for your database, and pass the schema to it. From then on, typeof users.$inferSelect gives the row type for free.

Checked against the current version of the SQL to Drizzle & TypeORM on .

Troubleshooting

The file does not open

Check that it is one of the supported formats above and opens in another app. Damaged files and password-protected PDFs cannot be read until they are repaired or unlocked.

It is slow or stops on a very large file

Everything runs on your device, so speed depends on its memory. Close other tabs, use a computer rather than a phone, or split the file into smaller parts first.

The download did not start

Look for your browser’s download bar or icon. Some browsers ask once before a site may download files; allow it and click the button again.

Frequently asked questions

Can I use the generated schema with drizzle-kit?

Yes. Point drizzle.config.ts at the file, then run drizzle-kit push against a test database, or drizzle-kit generate to create migrations. For an existing production database, compare first, because drizzle-kit will try to make the database match the file exactly.

Why are bigint columns written with mode number?

JavaScript numbers are exact only up to 2^53, while SQL BIGINT goes to 2^63. mode number is convenient for ids that will never get that large; switch to mode bigint for counters or values that might exceed the safe-integer range.

Does it generate Drizzle relations() as well?

It writes the foreign keys with .references(), which is what migrations need. The relations() helpers for the query API are optional and short to add once the tables exist.

Which TypeORM version is the output for?

Version 0.3 decorators, which are also used by NestJS. Column types are written as database type names, so check the type of each decimal or JSON column against your driver.

Keep working with the result

openWorkstand also includes a free workspace with documents, spreadsheets, tasks, projects and a calendar that save to a folder on your computer.