Quick answer
To convert SQL to a Prisma schema, turn each CREATE TABLE into a model, each column into a field with a Prisma scalar type and an @db native type, and each foreign key into a pair of relation fields. Playxoft's free SQL to Prisma Converter does this in your browser: paste PostgreSQL, MySQL or SQLite DDL and it writes schema.prisma with @id, @unique, @@index, enums and @map, in the same style prisma db pull produces.
- PostgreSQL, MySQL and SQLite
- Native @db types
- Relations on both sides
- Enums with @map
- Prisma 6 and 7 headers
- @map and @@map naming
- Line-numbered notes
How to use the SQL to Prisma Converter
- 1Choose your Source database: PostgreSQL, MySQL or SQLite.
- 2Paste your CREATE TABLE statements, drop a .sql dump onto the editor, or click Load example.
- 3Pick Naming: Prisma style for PascalCase models and camelCase fields mapped to your SQL names, or Keep SQL names.
- 4Choose your Prisma version for the generator and datasource blocks, or turn them off to paste models into an existing schema.
- 5Review the Notes, then copy or download schema.prisma and run
npx prisma validateandnpx prisma generate.
How are SQL types mapped to Prisma?
Prisma has a small set of scalar types (String, Int, BigInt, Float, Decimal, Boolean, DateTime, Json, Bytes). The exact database type is kept with a native type attribute such as @db.VarChar(255), so migrations recreate the same column:
| SQL type | Prisma field | PostgreSQL attribute | MySQL attribute |
|---|---|---|---|
integer / int | Int | none | none |
bigint | BigInt | none | @db.UnsignedBigInt if unsigned |
serial / AUTO_INCREMENT | Int @default(autoincrement()) | none | none |
varchar(255) | String | @db.VarChar(255) | @db.VarChar(255) |
text | String | none | @db.Text |
boolean / tinyint(1) | Boolean | none | none |
timestamptz | DateTime | @db.Timestamptz(6) | not available |
timestamp | DateTime | @db.Timestamp(6) | @db.Timestamp(0) |
datetime (MySQL) | DateTime | n/a | @db.DateTime(0) |
numeric(10,2) | Decimal | @db.Decimal(10, 2) | @db.Decimal(10, 2) |
json / jsonb | Json | @db.Json / none | none |
uuid | String | @db.Uuid | not available |
bytea / blob | Bytes | none | @db.Blob |
tsvector, interval… | Unsupported("…") | n/a | n/a |
Why @db.Timestamptz(6)? Prisma's default DateTime column is timestamp(3) (millisecond precision), while PostgreSQL defaults to 6 digits. Writing the precision explicitly stops prisma migrate from quietly changing your columns. SQLite has no native type attributes, so its fields are plain scalars.
How are foreign keys turned into Prisma relations?
Every foreign key becomes two fields. The model that holds the key gets a relation field with @relation(fields: […], references: […]); the referenced model gets a list field pointing back:
model Post {
id Int @id @default(autoincrement())
authorId Int @map("author_id")
author User @relation(fields: [authorId], references: [id], onDelete: Cascade, onUpdate: NoAction)
@@map("posts")
}
model User {
id Int @id @default(autoincrement())
posts Post[]
}If the foreign key columns are unique, the relation is one-to-one and the back field is optional (profile Profile?). When two models are linked more than once, or a table references itself, each relation gets a name such as @relation("EmployeeManager"), which Prisma requires to tell them apart.
Referential actions are written only when your SQL differs from Prisma's defaults: Prisma assumes onDelete: Restrict for required relations, SetNull for optional ones and onUpdate: Cascade. SQL without an ON UPDATE clause means NO ACTION, so the converter writes onUpdate: NoAction to keep your existing behavior instead of letting a later migration change it.
Should I use prisma db pull or this converter?
prisma db pull introspects a live database and is the most exact option when you can connect to it. This converter produces the same kind of schema from SQL text, which is faster when:
- you only have a migration file, a schema dump or a snippet from documentation;
- the database is not reachable from your machine, or you do not want to hand over credentials;
- you want to convert a single table, or try naming options and see the result instantly;
- you are moving a project from raw SQL or another ORM and want a starting schema.prisma before any database exists.
Use prisma db pull when you need views, @@ignore decisions made against real data, or extensions Prisma detects at runtime. Either way, run npx prisma validate on the result before generating a client.
How should Prisma models and fields be named?
Prisma's convention is PascalCase, singular model names (User, OrderItem) and camelCase field names (createdAt), while SQL databases usually use plural snake_case (order_items.created_at). You do not have to choose: @map and @@map keep the database names while your TypeScript uses Prisma names.
model OrderItem {
orderId Int @map("order_id")
unitPrice Decimal @map("unit_price") @db.Decimal(10, 2)
@@id([orderId, sku])
@@map("order_items")
}Choose Prisma style in Naming for this, or Keep SQL names to mirror the tables exactly, as prisma db pull does. Constraint names follow the same idea: Prisma expects users_pkey, users_email_key, users_email_idx and posts_author_id_fkey, so a map: argument is added only when your SQL uses a different name. Enum values that are not valid identifiers, such as in-progress, become in_progress @map("in-progress").
What can Prisma not represent?
Some SQL has no Prisma equivalent. Instead of failing, the converter keeps a valid schema and explains each case in the Notes panel:
- Tables without a primary key or unique column are marked
@@ignore, exactly likeprisma db pulldoes, because Prisma Client needs a unique identifier per row. - Types without a Prisma scalar (
tsvector,interval, PostGIS geometry, MySQLSET) becomeUnsupported("…")fields, readable through raw queries. - Partial and expression indexes and CHECK constraints are left as comments; keep them in a SQL migration.
- Generated columns become plain fields with a comment, since Prisma cannot mark a column as computed.
Need the same schema in TypeScript instead? The SQL to Drizzle converter reads the same input.
Frequently asked questions
Last updated by the Playxoft engineering team.