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.

circle-check
circle-info

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

Attribute
Description
Example

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:

Database
Auto-Increment
Primary Key
Foreign Key
Default Value
Nullable
Indexes
Description

PostgreSQL

βœ“

βœ“

βœ“

βœ“

βœ“

βœ“

βœ“

MySQL / MariaDB

βœ“

βœ“

βœ“ΒΉ

βœ“

βœ“

βœ“

βœ“

SQL Server / Azure SQL

βœ“

βœ“

βœ“

βœ“

βœ“

βœ“

βœ“

Oracle

βœ“

βœ“

βœ“Β²

βœ“

βœ“

βœ“

βœ“

Redshift

βœ“

βœ“Β³

βœ“Β³

βœ“

βœ“

—⁴

βœ“

Databricks

βœ“β΅

βœ“βΆ

βœ“βΆ

βœ“

βœ“

—⁷

βœ“

Snowflake

βœ“

βœ“βΈ

βœ“βΈ

βœ“

βœ“

β€”

βœ“

BigQuery

β€”

βœ“βΉ

βœ“βΉ

β€”

βœ“

β€”

βœ“

SQLite

βœ“ΒΉβ°

βœ“

βœ“ΒΉΒΉ

βœ“

βœ“

βœ“

β€”

DuckDB

β€”

βœ“

βœ“

β€”

βœ“

βœ“

βœ“

ClickHouse

β€”

βœ“ΒΉΒ²

β€”

βœ“

βœ“

β€”

βœ“

Legend: βœ“ = Supported | β€” = Not supported

Notes:

  1. MySQL/MariaDB: Foreign keys require InnoDB engine; MyISAM ignores FK constraints

  2. Oracle: Supports ON DELETE actions but not ON UPDATE actions for foreign keys

  3. Redshift: Primary keys and foreign keys are informational only (not enforced)

  4. Redshift: Does not support traditional indexes; use SORTKEY/DISTKEY instead

  5. Databricks: Auto-increment only supports BIGINT column type

  6. Databricks: Primary keys and foreign keys are informational only (not enforced); only NOT NULL is enforced

  7. Databricks: Does not support traditional indexes; use Z-ordering instead

  8. Snowflake: Primary keys and foreign keys are not enforced in standard tables (metadata only); only NOT NULL is enforced

  9. BigQuery: Primary keys and foreign keys use NOT ENFORCED syntax (metadata only for query optimization)

  10. SQLite: Auto-increment only works with INTEGER PRIMARY KEY columns

  11. SQLite: Foreign keys require PRAGMA foreign_keys = ON per connection (disabled by default)

  12. ClickHouse: Primary key defines sort order and sparse index; does not enforce uniqueness

Constraint Enforcement Matrix

circle-exclamation
Database
PK Enforced
FK Enforced
NOT NULL Enforced
Default 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

circle-info

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.

circle-info

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.

Attribute
Supported
Enforced

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 IDENTITY

  • Full foreign key support with ON DELETE and ON UPDATE actions

  • Column/table comments via COMMENT ON syntax

Enabling Schema Migration

Set the SLING_SCHEMA_MIGRATION environment variable to enable specific attributes:

Available Options

Value
Description

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.

circle-exclamation

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:

  1. Remove one table from the replication

  2. Disable foreign key migration

  3. Handle FK creation manually via hooks

Auto-Increment / Identity Columns

Sling migrates auto-increment columns with their seed and increment values:

Database-Specific Behavior

Source
Target
Result

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

Expression
SQL Server
PostgreSQL
MySQL
Oracle

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.

circle-info

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

  1. Test First: Run schema migration on a test environment before production

  2. Start Selective: Begin with primary_key only, then add more attributes

  3. Include All Dependencies: Ensure all FK-referenced tables are in the replication

  4. Use Full-Refresh: Schema attributes are best applied with full-refresh mode initially

  5. Review Generated Schema: After migration, review the target schema for any needed adjustments

  6. Consider Indexes Separately: Large tables may benefit from creating indexes after data load via hooks

See Also

Last updated

Was this helpful?