SQLite

Change existing tables from the live schema, without maintaining an ORM model.

Examples use Classic and Fluent tabs. Your choice follows you through the manual.

Automatic reconstruction

For supported changes, Migrator reads SQLiteTableInfo, changes its representation, creates a replacement table, copies mapped rows, swaps tables and recreates represented dependent objects. This provides column type/default/nullability changes and adding/removing primary, foreign, unique and check constraints.

Native rename and eligible drop-column paths are used when supported by the engine. Complex alterations use reconstruction. Existing rows must satisfy the new definition; a default does not rewrite every existing NULL during a column change.

Change a column on an existing SQLite table

Classic

Database.ChangeColumn("Users", new Column("Name", DbType.String, 500)
{
    IsNullable = false, DefaultValue = "Unknown",
    Collation = Collation.AsciiIgnoreCase
});

Fluent

migration.Alter.Column("Name").OnTable("Users")
    .AsString(500).NotNullable().WithDefaultValue("Unknown")
    .WithCollation(Collation.AsciiIgnoreCase);

Inside Up() / BuildUp(MigrationBuilder migration)

What survives a rebuild

DetailBehavior
Mapped dataNamed-column copy preserves mapped values, subject to the new definition accepting them.
Keys and constraintsNamed/composite keys, ordered foreign-key pairs and separate update/delete actions are retained.
Column collationsDeclared names are retained. Register custom collations on the connection.
Indexes and triggersSupported definitions are recreated; unsafe trigger rename/drop-column cases are rejected.
AUTOINCREMENTThe sequence high-water mark survives, including previously deleted identities.
Hidden rowidNot part of the mapped data and may change.

Boundaries are explicit

Reconstruction rejects generated columns, STRICT, WITHOUT ROWID and indexes with explicit COLLATE clauses. It is not an arbitrary SQL dependency rewriter. Adjust dependent views, complex expressions and triggers explicitly when required. MATCH FULL and MATCH PARTIAL are rejected because SQLite does not enforce their semantics.

Owned rebuild transactions and runner transactions validate foreign-key integrity before commit and restore the prior enforcement setting. For caller-owned active transactions configure foreign keys before beginning the transaction. A SQLite write lock is not a session-wide migration lease; coordinate deployment externally or provide IMigrationLock.

Values and identity

CLR Guid defaults use blobs from Guid.ToByteArray(), matching inserted parameters. Legacy text GUID defaults remain SQL expressions during unrelated rebuilds, so storage is not silently converted. Convert mixed text/blob keys explicitly and consistently across related tables.

SQLite INTEGER is signed 64-bit. Declared text lengths and decimal precision do not impose SQL Server-like enforcement. An identity needs a single INTEGER primary key in the same definition. For adding identity to an existing table, use an atomic SQLite RecreateTable definition containing both objects.

How this differs from other tools

FluentMigrator leaves general column alterations and later foreign-key changes to manual reconstruction. DbUp and Evolve run supplied scripts. EF Core also rebuilds SQLite tables using model-represented artifacts. Migrator reconstructs from live metadata without an ORM. The sourced operation comparison distinguishes native SQL, emulation and manual work.