Schema Migration
Examples of using Sling to migrate database schema attributes along with data
Schema migration (v1.5.7) is a powerful feature that allows Sling to replicate not just data, but also important schema attributes like primary keys, foreign keys, indexes, default values, nullable constraints, auto-increment columns, and column/table descriptions from source to target databases.
CLI Pro / Platform Feature: Schema migration requires a CLI Pro token or Platform Plan.
Schema migration is controlled via the SLING_SCHEMA_MIGRATION environment variable and is disabled by default.
Overview
When migrating databases, preserving schema attributes is often critical for maintaining data integrity and application compatibility. Sling's schema migration feature extracts extended metadata from source tables and applies the corresponding constraints and properties to target tables.
Supported Attributes
primary_key
Primary key constraints
id INT PRIMARY KEY
foreign_key
Foreign key relationships
REFERENCES customers(id)
indexes
Non-primary key indexes
CREATE INDEX idx_name ON table(col)
auto_increment
Identity/auto-increment columns
IDENTITY(1,1) or SERIAL
nullable
NOT NULL constraints
email VARCHAR(255) NOT NULL
default_value
Column default values
DEFAULT CURRENT_TIMESTAMP
description
Column and table comments
COMMENT ON COLUMN...
Supported Databases
Schema migration works between any combination of these databases. The level of support varies by databaseβsee the compatibility matrix below for details.
Full Support
PostgreSQL
MySQL / MariaDB
SQL Server / Azure SQL
Oracle
Redshift
Databricks
Partial Support
Snowflake (no indexes)
BigQuery (no auto-increment, no default values, no indexes)
SQLite (no descriptions)
DuckDB (no auto-increment, no default values)
ClickHouse (primary key, nullable, description only)
Database Compatibility Matrix
The following matrix shows which schema attributes are supported for each database:
PostgreSQL
β
β
β
β
β
β
β
MySQL / MariaDB
β
β
βΒΉ
β
β
β
β
SQL Server / Azure SQL
β
β
β
β
β
β
β
Oracle
β
β
βΒ²
β
β
β
β
Redshift
β
βΒ³
βΒ³
β
β
ββ΄
β
Databricks
ββ΅
ββΆ
ββΆ
β
β
ββ·
β
Snowflake
β
ββΈ
ββΈ
β
β
β
β
BigQuery
β
ββΉ
ββΉ
β
β
β
β
SQLite
βΒΉβ°
β
βΒΉΒΉ
β
β
β
β
DuckDB
β
β
β
β
β
β
β
ClickHouse
β
βΒΉΒ²
β
β
β
β
β
Legend: β = Supported | β = Not supported
Notes:
MySQL/MariaDB: Foreign keys require InnoDB engine; MyISAM ignores FK constraints
Oracle: Supports
ON DELETEactions but notON UPDATEactions for foreign keysRedshift: Primary keys and foreign keys are informational only (not enforced)
Redshift: Does not support traditional indexes; use SORTKEY/DISTKEY instead
Databricks: Auto-increment only supports
BIGINTcolumn typeDatabricks: Primary keys and foreign keys are informational only (not enforced); only NOT NULL is enforced
Databricks: Does not support traditional indexes; use Z-ordering instead
Snowflake: Primary keys and foreign keys are not enforced in standard tables (metadata only); only NOT NULL is enforced
BigQuery: Primary keys and foreign keys use
NOT ENFORCEDsyntax (metadata only for query optimization)SQLite: Auto-increment only works with
INTEGER PRIMARY KEYcolumnsSQLite: Foreign keys require
PRAGMA foreign_keys = ONper connection (disabled by default)ClickHouse: Primary key defines sort order and sparse index; does not enforce uniqueness
Constraint Enforcement Matrix
Important: Not all databases enforce constraints at runtime. Some databases accept constraint DDL for metadata/documentation purposes but do not validate data against those constraints. This matrix shows which constraints are actually enforced.
PostgreSQL
β Yes
β Yes
β Yes
β Yes
MySQL / MariaDB
β Yes
β Yes (InnoDB)
β Yes
β Yes
SQL Server
β Yes
β Yes
β Yes
β Yes
Oracle
β Yes
β Yes
β Yes
β Yes
Redshift
β No
β No
β Yes
β Yes
Databricks
β No
β No
β Yes
β Yes
Snowflake
β No
β No
β Yes
β Yes
BigQuery
β No
β No
β Yes
Partial
SQLite
β Yes
β Yes*
β Yes
β Yes
DuckDB
β Yes
β Yes
β Yes
β Yes
ClickHouse
β No
N/A
β No
β Yes
Legend: β Yes = Enforced at runtime | β No = Metadata only (not enforced) | * = Requires configuration
SQLite Note: Foreign key enforcement requires PRAGMA foreign_keys = ON to be set on each database connection. This is disabled by default for backwards compatibility.
Analytical Databases: Redshift, Snowflake, BigQuery, and Databricks are optimized for analytical workloads. They accept constraint definitions for documentation and query optimization hints, but do not enforce them at runtime. Data integrity must be validated upstream in ETL pipelines.
What You Can Use for Each Database
All features supported and enforced. PostgreSQL is fully compatible with schema migration.
Primary Key
β
β Yes
Foreign Key
β
β Yes
Auto-increment
β
β Yes
Default Value
β
β Yes
NOT NULL
β
β Yes
Indexes
β
Functional
Description
β
Metadata
Auto-increment uses
GENERATED BY DEFAULT AS IDENTITYFull foreign key support with
ON DELETEandON UPDATEactionsColumn/table comments via
COMMENT ONsyntax
All features supported and enforced (with InnoDB engine).
Primary Key
β
β Yes
Foreign Key
β
β Yes (InnoDB only)
Auto-increment
β
β Yes
Default Value
β
β Yes
NOT NULL
β
β Yes
Indexes
β
Functional
Description
β
Metadata
Auto-increment uses
AUTO_INCREMENTkeywordForeign keys require InnoDB engine (MyISAM ignores FK constraints)
Comments via
COMMENTclause
All features supported and enforced. SQL Server and Azure SQL are fully compatible.
Primary Key
β
β Yes
Foreign Key
β
β Yes
Auto-increment
β
β Yes
Default Value
β
β Yes
NOT NULL
β
β Yes
Indexes
β
Functional
Description
β
Metadata
Auto-increment uses
IDENTITY(seed, increment)syntaxForeign keys can be disabled with
NOCHECKif neededDescriptions via Extended Properties (
MS_Description)
All features supported and enforced with one limitation.
Primary Key
β
β Yes
Foreign Key
β
β Yes (ON DELETE only)
Auto-increment
β
β Yes
Default Value
β
β Yes
NOT NULL
β
β Yes
Indexes
β
Functional
Description
β
Metadata
Auto-increment uses
GENERATED BY DEFAULT AS IDENTITYForeign keys support
ON DELETEactions but notON UPDATE(Oracle limitation)Comments via
COMMENT ON COLUMN/COMMENT ON TABLE
DDL supported but constraints not enforced. Snowflake is an analytical database.
Primary Key
β
β No (metadata only)
Foreign Key
β
β No (metadata only)
Auto-increment
β
β Yes
Default Value
β
β Yes
NOT NULL
β
β Yes
Indexes
β
N/A
Description
β
Metadata
Auto-increment uses
AUTOINCREMENT START ... INCREMENT ...Primary keys and foreign keys are not enforced β they exist for documentation and query optimization only
Only
NOT NULLconstraints are enforced in standard tablesIndexes are not applicable (Snowflake uses clustering keys instead)
Limited support. BigQuery constraints are metadata only.
Primary Key
β
β No (NOT ENFORCED)
Foreign Key
β
β No (NOT ENFORCED)
Auto-increment
β
N/A
Default Value
β
N/A
NOT NULL
β
β Yes
Indexes
β
N/A
Description
β
Metadata
Primary keys and foreign keys use
NOT ENFORCEDsyntax (query optimization hints only)Column descriptions via
ALTER TABLE ... SET OPTIONSNo identity columnsβuse application-generated IDs or
GENERATE_UUID()
DDL supported but PK/FK not enforced. Redshift is an analytical data warehouse.
Primary Key
β
β No (informational)
Foreign Key
β
β No (informational)
Auto-increment
β
β Yes
Default Value
β
β Yes
NOT NULL
β
β Yes
Indexes
β
N/A
Description
β
Metadata
Auto-increment uses
IDENTITY(seed, increment)Primary keys and foreign keys are informational only β used as query optimizer hints, not enforced
Does not support traditional indexes; use
SORTKEYandDISTKEYfor performanceComments via
COMMENT ONsyntax
Most features supported. Foreign keys require explicit enabling.
Primary Key
β
β Yes
Foreign Key
β
β Yes (when enabled)
Auto-increment
β
β Yes
Default Value
β
β Yes
NOT NULL
β
β Yes
Indexes
β
Functional
Description
β
N/A
Auto-increment only works with
INTEGER PRIMARY KEYcolumnsForeign keys require
PRAGMA foreign_keys = ONper connection (disabled by default)No native column/table comment support
Partial support but constraints are enforced. DuckDB enforces integrity unlike most analytical DBs.
Primary Key
β
β Yes
Foreign Key
β
β Yes
Auto-increment
β
N/A
Default Value
β
N/A
NOT NULL
β
β Yes
Indexes
β
Functional
Description
β
Metadata
No native identity columnsβuse sequences with
DEFAULT nextval('seq')Foreign keys are enforced (unlike Snowflake, BigQuery, Redshift)
Indexes are fully supported via
duckdb_indexes()metadataColumn descriptions via
COMMENT ONsyntax
DDL supported but PK/FK not enforced. Databricks uses Delta Lake.
Primary Key
β
β No (informational)
Foreign Key
β
β No (informational)
Auto-increment
β
β Yes
Default Value
β
β Yes
NOT NULL
β
β Yes
Indexes
β
N/A
Description
β
Metadata
Auto-increment uses
GENERATED BY DEFAULT AS IDENTITY(BIGINT only)Note: When Databricks is used as a source, identity column detection is limited (Databricks doesn't expose identity metadata via
information_schema)Primary keys and foreign keys are informational only β used for query optimization
Only
NOT NULLandCHECKconstraints are enforcedDoes not support traditional indexes; use Z-ordering for performance
Limited support. ClickHouse is optimized for OLAP, not constraint enforcement.
Primary Key
β
β No (sort order only)
Foreign Key
β
N/A
Auto-increment
β
N/A
Default Value
β
β Yes
NOT NULL
β
β No
Indexes
β
N/A
Description
β
Metadata
Primary key defines sort order and sparse index β does not enforce uniqueness
No foreign key support
No auto-increment columns (use
generateSerialID()in v25.1+)NOT NULL is not enforced; use
Nullable(T)wrapper to allow NULLsUses data-skipping indexes (MinMax, Bloom) instead of traditional indexes
Enabling Schema Migration
Set the SLING_SCHEMA_MIGRATION environment variable to enable specific attributes:
Available Options
all
Enable all schema migration attributes
primary_key
Migrate primary key constraints
foreign_key
Migrate foreign key relationships
indexes
Migrate indexes (non-PK)
auto_increment
Migrate identity/auto-increment columns
nullable
Migrate NOT NULL constraints
default_value
Migrate column default values
description
Migrate column and table comments
Basic Example
Migrate all schema attributes from SQL Server to PostgreSQL:
Foreign Key Migration
When migrating foreign keys, Sling automatically handles table ordering to ensure parent tables are created before child tables that reference them.
All referenced tables must be included in the replication. If table orders has a foreign key to customers, both tables must be in the streams list.
Automatic Table Ordering
Sling performs topological sorting based on foreign key dependencies. Even if you list tables in the wrong order, they will be processed correctly:
Sling will automatically reorder streams to: customers β orders β order_items
Handling Circular Dependencies
If circular foreign key dependencies are detected, Sling will report an error. Options to resolve:
Remove one table from the replication
Disable foreign key migration
Handle FK creation manually via hooks
Auto-Increment / Identity Columns
Sling migrates auto-increment columns with their seed and increment values:
Database-Specific Behavior
SQL Server IDENTITY(1,1)
PostgreSQL
GENERATED BY DEFAULT AS IDENTITY
PostgreSQL SERIAL
MySQL
AUTO_INCREMENT
Oracle GENERATED AS IDENTITY
SQL Server
IDENTITY(seed, incr)
Default Values
Sling translates default value expressions between databases:
Default Value Translation
Current timestamp
GETDATE()
CURRENT_TIMESTAMP
CURRENT_TIMESTAMP
SYSDATE
UTC timestamp
GETUTCDATE()
CURRENT_TIMESTAMP AT TIME ZONE 'UTC'
UTC_TIMESTAMP()
SYS_EXTRACT_UTC(SYSTIMESTAMP)
UUID
NEWID()
gen_random_uuid()
UUID()
SYS_GUID()
Boolean true
1
true
1
1
Boolean false
0
false
0
0
Column & Table Descriptions
Migrate comments and descriptions to preserve documentation:
This will migrate:
Column comments (e.g.,
COMMENT ON COLUMN products.price IS 'Product retail price')Table comments (e.g.,
COMMENT ON TABLE products IS 'Product catalog')
Indexes
Migrate non-primary key indexes to preserve query performance:
This migrates regular indexes, unique indexes, and composite indexes.
Index names are automatically generated in the target database to avoid conflicts. The format is idx_{table}_{columns}.
Complete E-Commerce Migration Example
A comprehensive example migrating an e-commerce schema with all relationships:
Selective Attribute Migration
Enable only specific attributes based on your needs:
Data Integrity Focus
Performance Focus
Documentation Preservation
Using with Pipelines
Schema migration can also be used within pipelines:
Incremental Mode Considerations
Schema migration attributes are applied during table creation. When using incremental mode:
First run: Table is created with all schema attributes
Subsequent runs: Only data is upserted; schema is not modified
Troubleshooting
Missing Foreign Key Dependencies
Error: missing foreign key dependencies: 'orders' depends on 'customers' (not in stream list)
Solution: Add the missing referenced table to your streams:
Circular Dependency Detected
Error: circular foreign key dependency detected involving: table_a, table_b
Solution: Either disable FK migration or handle FKs manually with hooks:
Unsupported Default Expression
If a default expression cannot be translated, Sling will pass it through as-is with a debug warning. You may need to manually adjust the default in the target database.
Identity Column Conflicts
When using auto_increment migration, Sling uses GENERATED BY DEFAULT AS IDENTITY (PostgreSQL/Oracle) to allow explicit value inserts during data migration while still supporting auto-generation for new inserts.
Best Practices
Test First: Run schema migration on a test environment before production
Start Selective: Begin with
primary_keyonly, then add more attributesInclude All Dependencies: Ensure all FK-referenced tables are in the replication
Use Full-Refresh: Schema attributes are best applied with
full-refreshmode initiallyReview Generated Schema: After migration, review the target schema for any needed adjustments
Consider Indexes Separately: Large tables may benefit from creating indexes after data load via hooks
See Also
Last updated
Was this helpful?