T-SQL to PostgreSQL DDL Converter
Convert SQL Server CREATE TABLE statements to PostgreSQL DDL using a documented type mapping. Warnings list everything changed, dropped or left unmapped.
Private by design: everything you enter is processed in your browser. It is not sent to our servers.
How to use
- Paste one or more CREATE TABLE statements written for SQL Server (T-SQL). Comments, GO separators and bracketed names are fine.
- Choose how names are converted (snake_case, lower case, or preserved in quotes), whether IDENTITY becomes GENERATED BY DEFAULT or ALWAYS, and whether the dbo schema becomes public.
- Read the PostgreSQL DDL and then the warnings list. Every warning describes something that was changed, dropped or left for you to review.
- Copy or download the .sql file and run it against a test database before using it.
Worked example
A typical SQL Server table with an identity key, a GUID, nullable text, a bit flag, a decimal and a creation timestamp.
T-SQL input
CREATE TABLE [dbo].[CustomerOrder] (
[OrderId] INT IDENTITY(1,1) NOT NULL,
[CustomerGuid] UNIQUEIDENTIFIER NOT NULL DEFAULT NEWID(),
[Notes] NVARCHAR(MAX) NULL,
[Title] NVARCHAR(100) NOT NULL,
[IsPaid] BIT NOT NULL DEFAULT ((0)),
[Total] DECIMAL(10,2) NOT NULL,
[CreatedAt] DATETIME2(7) NOT NULL DEFAULT (GETDATE()),
CONSTRAINT [PK_CustomerOrder] PRIMARY KEY CLUSTERED ([OrderId] ASC)
) ON [PRIMARY];Result
| Warning 1 | Storage clauses after the column list (WITH, ON [PRIMARY], TEXTIMAGE_ON) were ignored. |
|---|---|
| Warning 2 | Fractional-second precision 7 exceeds PostgreSQL's maximum of 6; 6 was used (column "CreatedAt"). |
PostgreSQL output
CREATE TABLE public.customer_order (
order_id integer GENERATED BY DEFAULT AS IDENTITY NOT NULL,
customer_guid uuid NOT NULL DEFAULT gen_random_uuid(),
notes text,
title varchar(100) NOT NULL,
is_paid boolean NOT NULL DEFAULT false,
total numeric(10,2) NOT NULL,
created_at timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT pk_customer_order PRIMARY KEY (order_id)
);How it works
The converter tokenizes the T-SQL, finds each CREATE TABLE, splits the column list at top-level commas and converts every column and constraint with a fixed mapping table; there is no AI involved and the same input always gives the same output.
Types follow the mapping table on this page, each row of which links the Microsoft page for the SQL Server type and the PostgreSQL page for the target type. For example NVARCHAR(MAX) becomes text, DATETIME2(n) becomes timestamp(n), BIT becomes boolean, UNIQUEIDENTIFIER becomes uuid and TINYINT becomes smallint because PostgreSQL has no one-byte integer.
IDENTITY(seed, increment) becomes GENERATED BY DEFAULT AS IDENTITY (or ALWAYS, if you choose) with START WITH and INCREMENT BY when they differ from 1. BY DEFAULT is the default because data migrations usually need to load existing ids; ALWAYS rejects explicit values unless OVERRIDING SYSTEM VALUE is used.
Defaults: GETDATE() and SYSDATETIME() become CURRENT_TIMESTAMP, GETUTCDATE() becomes (now() AT TIME ZONE 'utc'), NEWID() becomes gen_random_uuid(), ((0)) on a bit column becomes false. Anything else is copied unchanged with a warning. Computed columns become generated columns: PERSISTED → STORED, otherwise VIRTUAL (PostgreSQL 18 or later).
Reserved words are quoted using the list of reserved key words from the PostgreSQL manual, so a column named User or Order becomes "user" or "order".
Common errors
No CREATE TABLE statement was found.- The input only contains other statements. Only CREATE TABLE is converted.
Unbalanced parentheses.- A parenthesis is missing or extra in your CREATE TABLE; check the end of the column list.
Unterminated 'string'.- A quoted string, [bracketed name] or comment is not closed.
Unknown type "…" (column "…") was copied unchanged. Check it exists in PostgreSQL.- The type is not in the mapping table. Replace it with the PostgreSQL type you want.
Type "geography" (column "…") has no automatic PostgreSQL equivalent; it was left as a commented placeholder.- Spatial, hierarchyid and sql_variant types need a manual choice (for example PostGIS).
Default for column "…" (…) was copied unchanged; check that it is valid PostgreSQL.- Rewrite the default using PostgreSQL syntax or functions.
Limits
- Only CREATE TABLE is converted. Indexes, views, stored procedures, triggers, sequences, ALTER statements and data are not.
- Expressions in CHECK constraints, computed columns and unrecognised defaults are copied verbatim; T-SQL functions in them will fail in PostgreSQL until you rewrite them.
- Collations, filegroups, compression, sparse columns, rowversion behaviour and clustered/non-clustered index choices have no direct equivalent and are dropped with a warning.
- datetimeoffset keeps only the instant, not the offset; fractional-second precision above 6 is reduced to 6.
- Always review the output and test it. The converter does not connect to any database.
Privacy
Your SQL is converted in your browser and never sent anywhere. Share links include the SQL only if it is short. No account is needed, no cookies are set and no analytics run. See thePrivacy Policy. The “Copy share link” button puts your settings after the “#” in the address; browsers do not send that part to servers, and the page’s canonical address never includes it.
FAQ
Why snake_case names by default?
PostgreSQL folds unquoted names to lower case, so CustomerOrder would become customerorder. snake_case keeps names readable without quoting. Choose “preserve” to keep exact case in double quotes.
Why is TINYINT smallint?
PostgreSQL has smallint (2 bytes), integer and bigint but no one-byte integer type.
Why does MONEY become numeric(19,4)?
It matches the fixed four decimal places without relying on the PostgreSQL money type, whose formatting depends on locale settings.
Does it migrate data?
No. It converts table definitions only.
Is NEWID() the same as gen_random_uuid()?
Both generate unique identifiers. NEWSEQUENTIALID() is the SQL Server function that generates ordered values; gen_random_uuid() is not ordered, so index behaviour can differ if you relied on sequential ids.
Related
Embed this tool
Paste this snippet into your own page or docs to show the tool inline. The embedded view works the same way (everything runs in the visitor’s browser) and carries a small link back to MakeTools.
Sources
- Microsoft: Data types (Transact-SQL) – checked 2026-10-14
- Microsoft: IDENTITY property – checked 2026-10-14
- PostgreSQL: Data types – checked 2026-10-14
- PostgreSQL: CREATE TABLE (identity columns) – checked 2026-10-14
- PostgreSQL: Generated columns – checked 2026-10-14
- PostgreSQL: UUID functions (gen_random_uuid) – checked 2026-10-14
- PostgreSQL: SQL key words appendix (reserved words) – checked 2026-10-14
Page last updated 2026-10-14. Written by Prajyot Mulik; see the editorial policy.