Migration Sources

Live databases and flat files, one tool

pgloader fetches source metadata over a live connection (or reads a file header directly) and builds the equivalent PostgreSQL schema automatically — schema translation, casting rules, and parallel data loading, for every source below.

MySQL

Fully automated schema + data migration

$ pgloader mysql://user@host/dbname pgsql://user@host/dbname

Automatic type casting (including the classic TINYINT(1)boolean and zero-date handling), catalog fetch over the live connection, and enum types translated to a named CREATE TYPE automatically. Recent work added .my.cnf credential lookup and binary/UUID/inet transform support.

MS SQL Server

Schema, indexes, and constraints — automatically

$ pgloader mssql://user@host/dbname pgsql://user@host/dbname

Automatic discovery of the schema, including indexes, primary and foreign key constraints. Recent releases added Azure AD authentication (MSAL4J), SEQUENCE migration, and multi-column foreign key fixes — sponsored work, funded through the support program.

SQLite

Automatic schema discovery, including indexes

$ pgloader sqlite:///path/to/file.db pgsql://user@host/dbname

No live connection needed — pgloader reads the SQLite file directly. Recent work added MATERIALIZE VIEWS support, letting you migrate from a view definition instead of a base table.

CSV, Fixed-Width, and DBF Files

A retry-wrapper on top of PostgreSQL's COPY protocol

For file-based sources, pgloader implements a retry policy around the load: if a COPY transaction fails partway through, the rejected rows are separated out and the accepted rows still make it to PostgreSQL — instead of the whole batch failing on one bad row.

LOAD CSV
     FROM 'data.csv' WITH ENCODING iso-646-us
          HAVING FIELDS (id, name, created_at)
     INTO postgresql:///dbname
          TARGET TABLE public.records
     WITH truncate, skip header = 1,
          fields optionally enclosed by '"',
          fields terminated by ','

DBF and fixed-width files work the same way — pgloader inspects the file header automatically for DBF, and a column-position spec for fixed-width text.

Oracle

Not built yet — open for funding

Oracle has never been a pgloader source. Building it into v4 over JDBC, the same way MySQL, MS SQL Server, and SQLite already work, is an open, threshold-funded campaign: below the threshold nothing is charged and nothing starts, above it work ships continuously in the open.

How the migration actually runs

Same 5-step pipeline, regardless of source

  1. 01

    Fetch catalogs

    Query the source's live catalogs (or read a file header) to build an in-memory schema representation — this is also where catalog mapping (renaming tables, remapping schemas) applies.

  2. 02

    Prepare the target

    Translate the source catalog into PostgreSQL's own, applying casting rules to column types and default values as it goes.

  3. 03

    Copy over COPY

    A reader thread selects from the source, a writer thread batches and transforms via the PostgreSQL COPY protocol — both running concurrently, per table.

  4. 04

    Parallel indexes

    Every index on a table builds in parallel once its data has landed — primary keys get a two-step treatment since PostgreSQL locks exclusively for those.

  5. 05

    Complete the schema

    Constraints and comments go on last: candidate unique indexes become primary keys, then foreign keys install as defined in the source.

Custom casting rules go in a .load file — here's a real one, casting a base64-encoded column straight to uuid:

load database
     from mysql://root@unix:/tmp/mysql.sock:3306/pgloader
     into postgresql://dim@localhost/pgloader

 CAST column base64.id to uuid drop typemod drop not null,
      column base64.data to jsonb using base64-decode;