Code converters

SQL to Drizzle Schema Converter

Paste SQL table definitions or a whole database dump and get a typed Drizzle schema.ts with indexes, enums, foreign keys and relations, ready for drizzle-kit.

  • Free foreverNo trial, no paywall, no usage limits.
  • No sign-upOpen the page and start. We never ask for an email to use a tool.
  • PrivateEverything runs in your browser. Your input is never uploaded or stored on our servers.
  • Works offlineOnce the page has loaded, the tool keeps working without a connection.
Source databaseThe SQL dialect of your DDL. It decides how quotes, types and auto-increment are read, and which ORM column types you get.
PostgreSQL, Supabase, Neon and pg_dump output.MySQL, MariaDB and PlanetScale, including mysqldump and phpMyAdmin exports.SQLite, Turso (libSQL) and Cloudflare D1, including sqlite3 .schema output.

SQL schema (DDL)

Reads tables, indexes, enum types, domains, comments and constraints added later with alter table. Drop a .sql file onto the editor to open it.
Clear

schema.ts

CopyDownload schema.ts
Paste table definitions, a pg_dump or a mysqldump. Nothing leaves your browser.

Need this built into your own API or pipeline? Talk to our team

Quick answer

To convert SQL to Drizzle, turn each CREATE TABLE into a pgTable, mysqlTable or sqliteTable call and each column type into its Drizzle builder, such as varchar({ length: 255 }) or timestamp({ withTimezone: true }). Playxoft's free SQL to Drizzle Converter does this in your browser: paste PostgreSQL, MySQL or SQLite DDL and it writes schema.ts with keys, defaults, indexes, enums and relations(). Check its notes, then run drizzle-kit generate.

  • PostgreSQL, MySQL and SQLite
  • Indexes and composite keys
  • pgEnum and mysqlEnum
  • relations() from foreign keys
  • camelCase keys, SQL names kept
  • pg_dump and mysqldump input
  • Line-numbered notes

How to use the SQL to Drizzle Converter

  1. 1Choose your Source database: PostgreSQL, MySQL or SQLite.
  2. 2Paste your CREATE TABLE statements, drop a .sql dump onto the editor, or click Load example.
  3. 3Set Dates, Bigint and camelCase keys to match how you want values to look in TypeScript.
  4. 4Read the Notes panel for anything skipped or approximated, and click a line number to jump to it in your SQL.
  5. 5Copy the code or download schema.ts, add it to your project and run npx drizzle-kit generate to produce the SQL and compare it with your original DDL.

What is Drizzle ORM?

Drizzle ORM is a TypeScript ORM where the schema is plain TypeScript: every table is a pgTable, mysqlTable or sqliteTable call, and the types of your rows are inferred from it, with no code generation step. Queries look like SQL (db.select().from(users).where(eq(users.id, 1))), and a second, relational API (db.query.users.findMany({ with: { posts: true } })) loads nested data.

Its companion CLI, drizzle-kit, turns changes to that schema into SQL migrations (generate) or applies them to a database directly (push). That is why an accurate schema.ts matters: if it does not describe the tables you already have, the next push tries to "fix" the difference. This converter keeps SQL names, constraint names and defaults intact so the schema matches your database instead of only coming close.

How are SQL types mapped to Drizzle column builders?

Each dialect has its own Drizzle package, so the same SQL type can map to different builders:

SQL typePostgreSQL (pg-core)MySQL (mysql-core)SQLite (sqlite-core)
integer / intinteger()int()integer()
bigintbigint({ mode: "number" })bigint({ mode: "number" })integer()
serial / AUTO_INCREMENTserial()int().autoincrement()integer().primaryKey({ autoIncrement: true })
varchar(255)varchar({ length: 255 })varchar({ length: 255 })text({ length: 255 })
booleanboolean()boolean() (tinyint(1))integer({ mode: "boolean" })
timestamptztimestamp({ withTimezone: true })timestamp()text()
numeric(10,2)numeric({ precision: 10, scale: 2 })decimal({ precision: 10, scale: 2 })numeric()
json / jsonbjson() / jsonb()json()text({ mode: "json" })
uuiduuid()char({ length: 36 })text()
enumpgEnum("name", […])mysqlEnum([…])text({ enum: […] })
text[]text().array()not supportednot supported

A few details trip people up. numeric and decimal columns return strings by default, so money never passes through a floating-point number. bigint needs a mode: "number" is exact only up to 2^53. SQLite has no date type, so date columns become text() unless you store Unix time. Types Drizzle does not ship, such as citext or tsvector, become a small customType declared at the top of the file.

How does the converter create foreign keys and relations?

Foreign keys become real constraints first. An unnamed single-column REFERENCES turns into .references(() => users.id, { onDelete: "cascade" }) on the column. Composite or named foreign keys go into the table's extra-config array as foreignKey({ name, columns, foreignColumns }), so the constraint name in your database is preserved.

Then, with Relations on, each foreign key also produces a pair of relations() entries for the relational query API:

export const postsRelations = relations(posts, ({ one, many }) => ({
  author: one(users, {
    fields: [posts.authorId],
    references: [users.id],
  }),
  comments: many(comments),
}));

Names come from the column (author_id becomes author) and the child table (posts). When two tables are linked more than once, or a table references itself, the converter adds a relationName so Drizzle can tell the relations apart, and self-references are typed with AnyPgColumn to avoid TypeScript's circular-type error.

Should I use drizzle-kit pull instead?

drizzle-kit pull introspects a live database and writes the schema for you. It is the right choice when you can connect to the database and want an exact snapshot. This converter is faster when you cannot, or do not want to:

Situationdrizzle-kit pullThis converter
You only have a .sql file, migration or dumpNeeds a running database firstPaste it and go
Production sits behind a VPN or firewallNeeds credentials and network accessNothing to connect
Converting one table or a snippetPulls the whole databaseConverts exactly what you paste
Trying naming and type optionsRerun with new config each timeToggle and see the result live
Views and row-level security policiesIntrospected where supportedSkipped, with a note

A common workflow is to convert here, commit the schema, then run drizzle-kit generate (no database connection needed) and diff the SQL it writes against your original DDL, or drizzle-kit push to a scratch database.

What does the converter not handle?

It reads tables, columns, keys, indexes, enums, domains and comments. Anything else is reported in the Notes panel with a line number rather than silently dropped:

  • Views, functions, triggers and policies are skipped: they are not part of a Drizzle table schema.
  • CHECK constraints are kept as comments above the table, so you can turn them into check() calls if you want drizzle-kit to manage them.
  • MySQL FULLTEXT indexes and prefix lengths (name(191)) have no Drizzle builder; create them in a custom migration.
  • Exclusion constraints and INHERITS are PostgreSQL features Drizzle cannot express.

If your SQL is messy, run it through the SQL formatter first; the line numbers in the notes are easier to follow in tidy SQL.

Frequently asked questions

No. It parses the SQL text you paste, entirely in your browser. No connection string is needed and nothing is uploaded, which makes it safe to use with production schema dumps.
Yes. COPY data blocks, SET statements and psql commands are skipped, and keys added later with ALTER TABLE, such as ADD CONSTRAINT ... PRIMARY KEY or phpMyAdmin's ADD KEY and MODIFY ... AUTO_INCREMENT, are applied to the right table.
Drizzle returns numeric and decimal values as strings so that amounts such as 19.99 are never rounded by a floating-point number. If you prefer numbers and accept the rounding risk, add mode: "number" to the column's config.
No. Foreign key constraints come from .references() and foreignKey(). relations() only powers the relational query API, db.query, so you can turn Relations off if you only use the SQL-like query builder.
A column that references its own table creates a circular type that TypeScript cannot infer. Annotating the callback's return type as AnyPgColumn, or AnyMySqlColumn and AnySQLiteColumn, breaks the cycle, which is the fix the Drizzle documentation recommends.
Current Drizzle ORM releases: column names are optional when they match the key, and indexes and composite keys use the array form of the table callback introduced in drizzle-orm 0.36.

Last updated by the Playxoft engineering team.

From the engineers who built this tool

Fighting messy data every day?

When payloads, schemas and integrations keep breaking, the fix is usually upstream. We design typed APIs and backends that stay clean as you grow. Tell us what you are building and we will suggest the simplest architecture that fits.

More free tools

See all tools

SQL Formatter

Beautify or minify SQL in 12 dialects, with keyword case, indent and line:column errors.

Open tool

cURL to Python Converter

New

Convert cURL commands into Python requests or httpx code with params, json, files and auth.

Open tool

cURL to Fetch Converter

New

Turn any cURL command into JavaScript fetch() code with headers, JSON, forms and auth.

Open tool

cURL to Axios Converter

New

Convert cURL commands into an Axios request config with params, data, auth and timeouts.

Open tool

SQL to Prisma Converter

Turn SQL DDL into a schema.prisma with native types, relations and enums.

Open tool

SVG to JSX Converter

Turn SVG markup or files into clean React and React Native components.

Open tool