πŸš€ Jump straight to schema translation

Paste your SQL Server CREATE TABLE statements and get PostgreSQL-ready SQL in seconds.

Translate SQL Server β†’ PostgreSQL Diff Two Schemas

Table of Contents

  1. Why Migrate from SQL Server to PostgreSQL?
  2. Pre-Migration Checklist
  3. Step 1: Export SQL Server Schema
  4. Step 2: Translate Schema to PostgreSQL
  5. Step 3: Migrate Your Data
  6. Step 4: Validate and Test
  7. Common Type Mapping Issues
  8. Migration Pitfalls to Avoid
  9. Frequently Asked Questions

Why Migrate from SQL Server to PostgreSQL?

Enterprise teams are increasingly moving from SQL Server to PostgreSQL for these reasons:

Pre-Migration Checklist

Step 1: Export SQL Server Schema

Use SQL Server Management Studio (SSMS) to generate schema scripts:

  1. Right-click your database β†’ Tasks β†’ Generate Scripts
  2. Select specific tables or script entire database
  3. In "Set Scripting Options", click Advanced
  4. Set "Types of data to script" to Schema only
  5. Set "Script for Server Version" to your target (or leave as current)

Alternatively, use sqlcmd or mssql-scripter from the command line:

mssql-scripter -S localhost -d MyDatabase -U sa --schema-and-data false \
  > sqlserver_schema.sql
Export one schema at a time if you have multiple schemas in SQL Server. PostgreSQL schemas are similar but permission models differ significantly.

Review the exported file for SQL Server-specific syntax:

Step 2: Translate Schema to PostgreSQL

SQL Server and PostgreSQL have fundamentally different type systems, identifier rules, and default behaviors.

Option A: Automated Translation (Fastest)

Use the SQL Dialect Translator to convert your SQL Server schema export to PostgreSQL syntax. It handles type mapping, identity column conversion, and identifier quoting.

Option B: SchemaLens Diff (Recommended for Schema Redesigns)

If you're modernizing the schema as part of migration, paste your SQL Server schema and target PostgreSQL schema into SchemaLens. It shows structural differences and generates migration SQL.

Option C: Manual Translation

For small schemas, manually rewrite CREATE TABLE statements using the type mapping table below.

πŸ› οΈ Save days of manual translation

The SQL Dialect Translator converts SQL Server schemas to PostgreSQL in seconds — including NVARCHAR→VARCHAR, IDENTITY→SERIAL, and bracketed identifier conversion.

Try the Translator β†’

Step 3: Migrate Your Data

After translating the schema and creating tables in PostgreSQL, move the data.

Option 1: Azure Database Migration Service (DMS) β€” Azure SQL Only

If migrating from Azure SQL Database or Azure SQL Managed Instance, use Azure DMS. It handles schema conversion, data movement, and cutover with minimal downtime.

Option 2: pg_dump / pg_restore with Foreign Data Wrapper

For on-premise SQL Server, use the tds_fdw foreign data wrapper to connect PostgreSQL directly to SQL Server:

-- In PostgreSQL
CREATE EXTENSION tds_fdw;

CREATE SERVER sqlserver_server
  FOREIGN DATA WRAPPER tds_fdw
  OPTIONS (servername 'sqlserver_host', port '1433', database 'MyDB');

CREATE USER MAPPING FOR postgres
  SERVER sqlserver_server
  OPTIONS (username 'sa', password 'password');

-- Import foreign schema
IMPORT FOREIGN SCHEMA dbo
  FROM SERVER sqlserver_server
  INTO public;

Option 3: Custom ETL with Python

For complex transformations, use Python with pyodbc and SQLAlchemy:

import pandas as pd
from sqlalchemy import create_engine

sqlserver = create_engine('mssql+pyodbc://user:pass@dsn')
postgres = create_engine('postgresql://user:pass@host/db')

# Read from SQL Server
df = pd.read_sql('SELECT * FROM dbo.Users', sqlserver)

# Transform if needed (e.g., convert UNIQUEIDENTIFIER to UUID string)
df['id'] = df['id'].astype(str)

# Write to PostgreSQL
df.to_sql('users', postgres, if_exists='append', index=False)

Option 4: SSIS β†’ PostgreSQL ODBC

Use SQL Server Integration Services (SSIS) with a PostgreSQL ODBC driver. This is common in enterprise environments that already have SSIS packages.

Watch out for collation differences. SQL Server collation (e.g., SQL_Latin1_General_CP1_CI_AS) determines case sensitivity and sorting. PostgreSQL uses collation at the database or column level. Ensure your PostgreSQL collation matches application expectations.

Step 4: Validate and Test

Enterprise migrations require rigorous validation:

Schema Validation

Data Validation

Application Testing

Use SchemaLens for Diff Validation

Export both schemas and diff them:

-- SQL Server (via SSMS or sqlcmd)
-- Generate Scripts β†’ Schema Only

-- PostgreSQL
pg_dump --schema-only -U postgres mydb > postgres_schema.sql

Then paste both into SchemaLens to catch any remaining differences.

πŸ” Catch schema differences before go-live

SchemaLens compares your SQL Server and PostgreSQL schemas side-by-side and highlights tables, columns, indexes, and constraints that didn't migrate correctly.

Compare Schemas Free β†’

Common Type Mapping Issues

SQL Server TypePostgreSQL TypeNotes
INT IDENTITY(1,1)SERIALUse BIGSERIAL for BIGINT identity
BIGINT IDENTITY(1,1)BIGSERIALDirect equivalent
BITBOOLEANSQL Server BIT can be 0, 1, or NULL
TINYINTSMALLINTPostgreSQL has no unsigned types
SMALLINTSMALLINTNo change needed
INTINTEGERNo change needed
BIGINTBIGINTNo change needed
FLOATDOUBLE PRECISIONOr REAL for 4-byte float
REALREALNo change needed
DECIMAL(p,s)NUMERIC(p,s)No change needed
MONEYNUMERIC(19,4)PostgreSQL has MONEY but it's discouraged
SMALLMONEYNUMERIC(10,4)No direct equivalent
VARCHAR(n)VARCHAR(n)No change needed
NVARCHAR(n)VARCHAR(n)PostgreSQL uses UTF-8 natively
CHAR(n)CHAR(n)No change needed
NCHAR(n)CHAR(n)PostgreSQL uses UTF-8 natively
TEXTTEXTNo change needed
NTEXTTEXTDeprecated in SQL Server anyway
VARCHAR(MAX)TEXTPostgreSQL TEXT is unlimited
NVARCHAR(MAX)TEXTPostgreSQL TEXT is unlimited
DATETIMETIMESTAMPOr TIMESTAMPTZ with timezone
DATETIME2TIMESTAMPHigher precision than DATETIME
SMALLDATETIMETIMESTAMPLess precision, same mapping
DATETIMEOFFSETTIMESTAMPTZTimezone-aware timestamp
DATEDATENo change needed
TIMETIMENo change needed
UNIQUEIDENTIFIERUUIDUse gen_random_uuid() as default
BINARY(n)BYTEAFixed-length binary
VARBINARY(n)BYTEAVariable-length binary
IMAGEBYTEADeprecated in SQL Server
VARBINARY(MAX)BYTEAFor large binary objects
XMLXMLPostgreSQL has native XML type
SQL_VARIANTJSONB or TEXTNo direct equivalent; redesign recommended

Migration Pitfalls to Avoid

Frequently Asked Questions

How long does a SQL Server to PostgreSQL migration take?

For a 50-100 table schema with under 100GB of data, plan for 1-2 weeks including testing. Large enterprise schemas (1000+ tables) with TB-scale data can take 1-3 months. The schema translation is typically 20% of the effort; data migration, stored procedure rewriting, and application testing consume the rest.

Can we migrate without downtime?

Yes, using logical replication or change data capture (CDC). Tools like Debezium can stream SQL Server changes to PostgreSQL in real-time. Azure DMS also supports online migration for Azure SQL Database.

What about SQL Server Agent jobs?

SQL Server Agent jobs must be rewritten. In PostgreSQL, use pg_cron extension for scheduled tasks, or external schedulers like Linux cron, Airflow, or Dagster.

How do we handle SQL Server Reporting Services (SSRS)?

SSRS doesn't exist in PostgreSQL. Options include: Metabase, Apache Superset, Grafana, or commercial tools like Tableau and Power BI (which connect to PostgreSQL natively).

Is Azure Database for PostgreSQL a good target?

Yes, if you're already in Azure. It's fully managed PostgreSQL with built-in backups, monitoring, and scaling. However, self-managed PostgreSQL on Azure VMs or AKS gives you more control over extensions and configuration.

Do we need to rewrite all stored procedures?

Most likely yes. T-SQL and PL/pgSQL are different languages. Simple procedures may translate automatically, but complex logic with cursors, dynamic SQL, or CLR integration will need manual rewriting. Consider moving business logic to the application layer where possible.

Ready to migrate? Start with your schema.

Convert your SQL Server CREATE TABLE statements to PostgreSQL syntax in seconds, then diff the result to catch anything the translator missed.

Translate Schema β†’ Diff & Validate β†’