pgferry defaults to conservative, mostly lossless mappings. The main default exception is JSON, which becomes PostgreSQL jsonb because that is usually the more useful target type.
With datetime_as_timestamptz = true, maps to timestamptz. plan emits a temporal warning: SQLite values have no timezone, so PostgreSQL session timezone is load-bearing.
DATE
date
JSON
jsonb
json when json_as_jsonb = false
SQLite accepts datetime_as_timestamptz for DATETIME / TIMESTAMP. Other MySQL-family-only and MSSQL-only type-mapping options are rejected during config validation.
datetime2 and time carry fractional-second scale from sys.columns; pgferry emits PostgreSQL timestamp(n), timestamptz(n), or time(n) when scale > 0, with n clamped to 6 (SQL Server allows scale 7).
source_snapshot_mode = "single_tx" uses SNAPSHOT isolation and requires ALLOW_SNAPSHOT_ISOLATION ON on the source database.
uniqueidentifier values are byte-reordered into standard UUID order during copy.
nvarchar and nchar lengths are divided by two because MSSQL reports byte length, not character length.
(max) types map to PostgreSQL text or bytea.
Computed columns are copied as materialized values and reported for manual semantic recreation.
Leave most type mapping at defaults for the first rehearsal.
Turn on semantic remaps like tinyint1_as_boolean, binary16_as_uuid, or string_uuid_as_uuid only when you know the source data actually follows that convention.
Prefer unknown_as_text = false for production rehearsals so pgferry surfaces unsupported types early instead of hiding them behind generic text columns.