Skip to main content

SQL to Code

Turn CREATE TABLE DDL into TypeScript, Go, Java, Python or C# model code — with nullability handled correctly. Runs in your browser — nothing is sent to a server.

Samples:

How to Use SQL to Code

  1. Paste your CREATE TABLE statements into the left panel, or click a sample button to load one.
  2. Pick a target language from the tabs — TypeScript, Go, Java, Python or C#. The output regenerates instantly.
  3. Choose a model name style. PascalCase turns user_addresses into UserAddresses; leave Singularize on to get UserAddress.
  4. Enable Include SQL type as comment to annotate every field with its original column type, nullability and default — useful during a migration review.
  5. Copy the generated code with the Copy button and drop it into your project.

Multiple CREATE TABLE statements in one paste produce one model per table, in the order they appear. Table-level constraint lines such as PRIMARY KEY (id), FOREIGN KEY, UNIQUE KEY and CHECK are recognised and skipped, so they never leak in as bogus fields.

Why Generate Model Code From Your DDL?

Your database schema is the real contract. The application types that sit on top of it — a TypeScript interface for a row, a Go struct scanned from a query, a Java entity, a Python dataclass, a C# POCO — are a hand-written copy of that contract, and hand-written copies drift. Someone widens a column, adds a field, or drops a NOT NULL, and the model in the codebase silently keeps describing last month's schema.

Generating the model straight from the DDL removes the transcription step entirely. You paste the same CREATE TABLE that your migration applies, and you get types that match it column for column. It is fastest exactly where hand-writing is most painful: a legacy table with forty columns, an inherited schema you did not design, a quick script against a reporting database, or the first draft of a repository layer before you reach for a full ORM.

  • Migration reviews: paste the old and new DDL and diff the two generated models to see exactly what changed for consumers.
  • Onboarding a legacy schema: get a readable, typed picture of tables nobody has documented.
  • API layer scaffolding: a row type is usually the starting point for a DTO or response body.
  • Cross-language teams: the same table, described consistently for the Go service and the TypeScript client.

Nullability: The Default Is Backwards

This is the single detail that makes DDL-to-code conversion worth doing carefully. In SQL, a column is nullable unless you explicitly write NOT NULL. That is the opposite of the default assumption in almost every programming language: a Go string, a Java int, a C# int, a Python str annotation and a TypeScript string all read as "a value is always present" unless you say otherwise.

So a plain nickname VARCHAR(100) is nullable, and a model that types it as a plain non-optional string is lying. What follows is familiar: a null-pointer exception when the driver scans NULL into a Go string, a NullPointerException unboxing a Java Integer into an int, or a TypeScript type that says a field is a string while the JSON on the wire carries null and the compiler never warns you.

This tool reads the flag per column and applies the right idiom for each target language:

Language NOT NULL column Nullable column
TypeScriptnumbernumber | null
Gostring*string (pointer)
Javaint (primitive)Integer (boxed)
PythonintOptional[int]
C#intint?

A few extra rules fall out of SQL semantics and are applied automatically. An inline PRIMARY KEY implies NOT NULL, so primary keys are never generated as optional. PostgreSQL SERIAL and BIGSERIAL expand to a NOT NULL integer, so they are treated as non-optional too. And note that a DEFAULT clause does not make a column non-nullable — a default only fills in a value when you omit the column on insert; an explicit NULL still lands in the row.

SQL Type Mapping Reference

Common MySQL, PostgreSQL and SQL Server column types map as follows. Lengths and precision such as VARCHAR(255) or DECIMAL(10,2) are parsed and preserved in the optional comment, since no target language encodes them in the type itself.

SQL type TypeScript Go Java Python C#
INT, SMALLINT, TINYINT, SERIALnumberintintintint
BIGINT, BIGSERIALnumberint64longintlong
DECIMAL, NUMERIC, MONEYnumberfloat64BigDecimalDecimaldecimal
FLOAT, REAL, DOUBLEnumberfloat64doublefloatdouble
BOOLEAN, BOOL, BIT(1), TINYINT(1)booleanboolbooleanboolbool
CHAR, VARCHAR, NVARCHAR, TEXT, ENUMstringstringStringstrstring
DATEstringtime.TimeLocalDatedateDateOnly
TIMEstringtime.TimeLocalTimetimeTimeOnly
DATETIME, TIMESTAMPstringtime.TimeLocalDateTimedatetimeDateTime
TIMESTAMPTZstringtime.TimeOffsetDateTimedatetimeDateTimeOffset
JSON, JSONBRecordjson.RawMessageStringAnystring
UUID, UNIQUEIDENTIFIERstringstringUUIDUUIDGuid
BLOB, BYTEA, VARBINARYstring[]bytebyte[]bytesbyte[]

What the Parser Handles

  • Multiple statements: paste an entire schema file and get one model per CREATE TABLE.
  • Quoted and qualified names: backticks, double quotes and square brackets are all accepted, and public.users or [dbo].[Posts] reduce to the table name.
  • IF NOT EXISTS, TEMPORARY and UNLOGGED variants.
  • Nested parentheses: DECIMAL(10,2), CHECK (qty > 0) and enum value lists do not prematurely end the column list, and the comma inside DECIMAL(10,2) is not treated as a column separator.
  • Comments: both -- line comments and block comments are stripped before parsing, while identical character sequences inside string literals are left untouched.
  • Column attributes: NOT NULL, DEFAULT, AUTO_INCREMENT, IDENTITY, PRIMARY KEY, UNIQUE, REFERENCES, MySQL COMMENT, UNSIGNED and PostgreSQL array suffixes.
  • Case insensitivity: keywords work in upper, lower or mixed case.

Everything runs in your browser. The DDL you paste never leaves the page — no upload, no server round trip, no logging. That matters, because a schema dump is often the most revealing document about an internal system that exists.

Specifications

Accepts
Text — type or paste
Gives you
copy to clipboard
Where it runs
Your browser — the file is never uploaded
Sign-up
None
Cost
Free, with no usage limits

FAQ

Why is my column generated as optional when I did not ask for it?

Because SQL made it optional. A column is nullable unless the definition explicitly says NOT NULL, so a bare "nickname VARCHAR(100)" can hold NULL and the generated field reflects that. If the column should never be null, add NOT NULL to the DDL and regenerate — the field becomes a plain non-optional type. A DEFAULT clause does not change this: a default only supplies a value when the column is omitted on insert, and an explicit NULL still gets stored.

Does a PRIMARY KEY column come out nullable?

No. An inline PRIMARY KEY implies NOT NULL in every SQL dialect, so those columns are always generated as non-optional even if NOT NULL is not written out. The same applies to PostgreSQL SERIAL and BIGSERIAL, which expand to a NOT NULL integer with a sequence default. A trailing table-level PRIMARY KEY (id) line is recognised as a constraint and skipped, so it never appears as a phantom field.

How are table-level constraints handled?

They are detected and skipped rather than parsed as columns. That covers PRIMARY KEY (...), FOREIGN KEY ... REFERENCES ..., UNIQUE and UNIQUE KEY, CONSTRAINT ... , INDEX and KEY definitions, and CHECK (...). This is the classic failure mode of naive DDL parsers — a trailing "PRIMARY KEY (id)" line becomes a column literally named PRIMARY — and it is explicitly covered here.

Can I paste a whole schema dump with many tables?

Yes. Every CREATE TABLE statement in the input produces its own model, emitted in source order. Statements the tool does not model — INSERT, ALTER TABLE, CREATE INDEX, SET, and so on — are ignored rather than treated as errors, so you can paste a mysqldump or a pg_dump section directly.

Why does DECIMAL map to float64 in Go and BigDecimal in Java?

Because those are the pragmatic defaults for each ecosystem. Java has a first-class arbitrary-precision decimal type, so DECIMAL and NUMERIC map to BigDecimal, and C# has a native decimal, while Python uses Decimal. Go has no decimal type in the standard library, so float64 is the generated default — for money columns you will usually want to swap it for a dedicated decimal package or store minor units in an integer. Same caution applies to BIGINT in TypeScript: values beyond 2^53 lose precision as a JavaScript number, so consider typing those as string if your IDs are large.

Is my SQL sent anywhere?

No. The parser and all five code generators run entirely in your browser as client-side JavaScript. Nothing is uploaded, stored or logged, and the tool keeps working with the network disconnected. You can paste production DDL without it leaving your machine.

Related Tools