---
title: "Migration Toolkit Schema"
description: "The Migration Toolkit Schema subsystem forms the structural bridge between user-defined TypeScript database layouts in Drizzle ORM and physical database state. It operates across multiple target di..."
last_updated: "2026-10-12T08:14:00.734142+00:00"
canonical_url: "https://www.doc0.dev/docs/e1b68fed-3c4e-4c95-b2ba-ebf050f78025/technical/migration-toolkit/migration-toolkit-schema"
---

<details>
<summary>Relevant source files</summary>

The following files were used as context for generating this wiki page:

- [drizzle-kit/src/serializer/gelSchema.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-kit/src/serializer/gelSchema.ts)
- [drizzle-kit/src/snapshotsDiffer.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-kit/src/snapshotsDiffer.ts)
- [drizzle-kit/src/jsonStatements.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-kit/src/jsonStatements.ts)
- [drizzle-kit/src/introspect-pg.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-kit/src/introspect-pg.ts)
- [drizzle-kit/src/introspect-singlestore.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-kit/src/introspect-singlestore.ts)
- [drizzle-kit/src/introspect-gel.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-kit/src/introspect-gel.ts)
- [drizzle-kit/src/api.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-kit/src/api.ts)
- [drizzle-kit/src/serializer/pgSchema.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-kit/src/serializer/pgSchema.ts)
- [drizzle-kit/src/introspect-mysql.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-kit/src/introspect-mysql.ts)
- [drizzle-kit/src/serializer/sqliteSchema.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-kit/src/serializer/sqliteSchema.ts)
- [drizzle-kit/src/serializer/gelSerializer.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-kit/src/serializer/gelSerializer.ts)
- [drizzle-kit/src/serializer/singlestoreSchema.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-kit/src/serializer/singlestoreSchema.ts)
- [drizzle-kit/src/serializer/mysqlSchema.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-kit/src/serializer/mysqlSchema.ts)
- [drizzle-typebox/src/column.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-typebox/src/column.ts)
- [drizzle-arktype/src/column.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-arktype/src/column.ts)
- [integration-tests/drizzle2/mysql/meta/_journal.json](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/integration-tests/drizzle2/mysql/meta/_journal.json)
- [integration-tests/drizzle2/singlestore/meta/0000_snapshot.json](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/integration-tests/drizzle2/singlestore/meta/0000_snapshot.json)
- [integration-tests/drizzle2/pg/meta/_journal.json](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/integration-tests/drizzle2/pg/meta/_journal.json)
- [drizzle-seed/src/types/drizzleStudio.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/types/drizzleStudio.ts)
- [integration-tests/drizzle2/mysql-proxy/first/meta/0000_snapshot.json](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/integration-tests/drizzle2/mysql-proxy/first/meta/0000_snapshot.json)
- [integration-tests/drizzle2/mysql-proxy/second/meta/0000_snapshot.json](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/integration-tests/drizzle2/mysql-proxy/second/meta/0000_snapshot.json)
- [drizzle-kit/src/cli/commands/libSqlPushUtils.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-kit/src/cli/commands/libSqlPushUtils.ts)
- [drizzle-kit/src/cli/commands/mysqlPushUtils.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-kit/src/cli/commands/mysqlPushUtils.ts)
- [drizzle-kit/src/cli/commands/pgPushUtils.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-kit/src/cli/commands/pgPushUtils.ts)
- [drizzle-kit/src/cli/commands/push.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-kit/src/cli/commands/push.ts)
- [drizzle-kit/src/cli/commands/singlestorePushUtils.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-kit/src/cli/commands/singlestorePushUtils.ts)
- [drizzle-kit/src/cli/commands/sqlitePushUtils.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-kit/src/cli/commands/sqlitePushUtils.ts)
- [drizzle-kit/src/migrationPreparator.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-kit/src/migrationPreparator.ts)
- [drizzle-kit/src/serializer/index.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-kit/src/serializer/index.ts)
</details>

## Overview

The Migration Toolkit Schema subsystem forms the structural bridge between user-defined TypeScript database layouts in Drizzle ORM and physical database state. It operates across multiple target dialects—PostgreSQL, MySQL, SQLite (including LibSQL/Turso), SingleStore, and Gel—by translating code definitions and live database introspections into versioned, normalized JSON snapshots and migration journals.

Sources: [drizzle-kit/src/api.ts:64-92](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-kit/src/api.ts#L64-L92)

At its core, this architecture decouples schema representation from specific database drivers. By validating schema objects against Zod structural specifications, `drizzle-kit` can diff successive snapshots, compute granular change sets (`jsonStatements`), filter out non-breaking or pseudo-changes (such as automatic type promotions), and safely apply structural mutations or generate migration files.

Sources: [drizzle-kit/src/serializer/index.ts:12-56](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-kit/src/serializer/index.ts#L12-L56)

```mermaid
graph TD
    A["TypeScript Schema Definition"] --> B["Serialization Modules<br>(serializePg, serializeMySql, etc.)"]
    C["Live Database Catalog"] --> D["Database Introspection<br>(pgPushIntrospect, mysqlPushIntrospect, etc.)"]
    B --> E["Normalized JSON Snapshot<br>(pgSchema, mysqlSchema, sqliteSchema)"]
    D --> E
    E --> F["Snapshots Differ Engine<br>(applyPgSnapshotsDiff, etc.)"]
    F --> G["Intermediate JSON Statements<br>(JsonStatement[])"]
    G --> H["SQL Generator & Push Engine<br>(fromJson, pushSchema, pushMySQLSchema)"]
```

Sources: [drizzle-kit/src/snapshotsDiffer.ts:1-16](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-kit/src/snapshotsDiffer.ts#L1-L16)

---

## Schema Diffing and SQL Generation

The schema diffing subsystem compares a previous schema snapshot (`json1`) against a current schema snapshot (`json2`) to produce an intermediate array of semantic JSON statement descriptors. These descriptors are subsequently lowered into concrete SQL queries by the SQL generator or filtered and executed by the push utilities.

Sources: [drizzle-kit/src/snapshotsDiffer.ts:98-123](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-kit/src/snapshotsDiffer.ts#L98-L123)

When generating migrations or pushing schema updates, `applyPgSnapshotsDiff`, `applyMysqlSnapshotsDiff`, and related diffing functions inspect tables, columns, constraints, foreign keys, and indexes. For dialects like SQLite and LibSQL where table alterations are restricted, the differ identifies situations requiring table recreation (`recreate_table`) via temporary tables and data copying (`_moveDataStatements`).

Sources: [drizzle-kit/src/api.ts:159-186](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-kit/src/api.ts#L159-L186)

```mermaid
sequenceDiagram
    participant CLI as Push / Migrate CLI
    participant Diff as snapshotsDiffer
    participant Gen as jsonStatements / sqlgenerator
    participant DB as Target Database
    CLI->>Diff: applyPgSnapshotsDiff(squashedPrev, squashedCur, ...)
    Diff-->>CLI: { statements, _meta }
    CLI->>Gen: fromJson(statements, dialect, mode, json2)
    Gen-->>CLI: SQL string array (statementsToExecute)
    CLI->>DB: Execute queries (with safety checks)
    DB-->>CLI: Acknowledge completion
```

Sources: [drizzle-kit/src/cli/commands/libSqlPushUtils.ts:28-111](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-kit/src/cli/commands/libSqlPushUtils.ts#L28-L111)

The table below outlines common statement types generated during the diffing process and their structural targets across dialects:

| Statement Type | Description | Target Dialects |
| :--- | :--- | :--- |
| `create_table` | Provisions a new database table with columns and constraints | PostgreSQL, MySQL, SingleStore, SQLite |
| `drop_table` | Removes a table and verifies dependent row counts | All Dialects |
| `alter_table_add_column` | Appends a column definition to an existing table | All Dialects |
| `alter_table_drop_column` | Drops a column after checking for item counts | All Dialects |
| `recreate_table` | Rebuilds SQLite/LibSQL tables via temporary `__new_` tables | SQLite, LibSQL |
| `create_type_enum` | Creates native enumeration types | PostgreSQL |

Sources: [drizzle-kit/src/jsonStatements.ts:45-111](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-kit/src/jsonStatements.ts#L45-L111), [drizzle-kit/src/cli/commands/libSqlPushUtils.ts:32-64](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-kit/src/cli/commands/libSqlPushUtils.ts#L32-L64)

---

## Schema Push Mechanics

Schema push operations (`pushSchema`, `mysqlPush`, `pgPush`, `sqlitePush`, `libSQLPush`) synchronize a live database instance with the TypeScript schema without generating explicit migration files. They achieve this by introspecting the live database catalog into a normalized schema structure, serializing the target TypeScript schema, running the snapshot differ, filtering pseudo-changes, and prompting users when destructive operations are detected.

Sources: [drizzle-kit/src/api.ts:125-188](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-kit/src/api.ts#L125-L188)

Filtering mechanisms prevent redundant updates, such as boolean default variations or automatic promotions between `bigint unsigned` and `serial` column types in MySQL and SingleStore. Furthermore, safety validation layers inspect live row counts before executing destructive statements such as dropping tables or columns, adding non-null columns without defaults, or modifying primary keys.

Sources: [drizzle-kit/src/cli/commands/mysqlPushUtils.ts:10-105](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-kit/src/cli/commands/mysqlPushUtils.ts#L10-L105)

> [!WARNING]
> When pushing changes to SQLite or LibSQL databases, adding a `NOT NULL` column without a default value to a populated table triggers an automatic table truncation or forces deletion of rows to prevent constraint violations.

Sources: [drizzle-kit/src/cli/commands/libSqlPushUtils.ts:173-196](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-kit/src/cli/commands/libSqlPushUtils.ts#L173-L196)

The following example demonstrates how programmatic schema pushing is invoked using `pushSchema` for PostgreSQL:

```typescript
import { pushSchema } from 'drizzle-kit/api';
import { drizzle } from 'drizzle-orm/node-postgres';
import * as schema from './schema';

const dbInstance = drizzle(process.env.DATABASE_URL!);

async function syncSchema() {
  const result = await pushSchema(schema, dbInstance, ['public'], ['__drizzle_migrations']);
  
  if (result.hasDataLoss) {
    console.warn('Warnings:', result.warnings);
  }
  
  await result.apply();
  console.log('Schema pushed successfully.');
}
```

Sources: [drizzle-kit/src/api.ts:125-188](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-kit/src/api.ts#L125-L188)

---

## Schema Snapshot Serializer

The snapshot serializer transforms AST exports and database reflection results into versioned, structured Zod-validated JSON documents. Each dialect maintains strict validation schemas (e.g., `pgSchemaInternal`, `schemaInternal` for SQLite and SingleStore, `gelSchemaExternal`) capturing tables, columns, indexes, foreign keys, composite primary keys, check constraints, unique constraints, and policies.

Sources: [drizzle-kit/src/serializer/pgSchema.ts:365-438](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-kit/src/serializer/pgSchema.ts#L365-L438)

Versioning ensures backward compatibility across migration toolkit upgrades. For example, PostgreSQL snapshots have evolved through versions `3` through `7`, introducing proper schema namespace support (`schema.table` notation), sequence metadata tracking, and internal kit state tracking (`kitInternals`).

Sources: [drizzle-kit/src/serializer/sqliteSchema.ts:82-132](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-kit/src/serializer/sqliteSchema.ts#L82-L132), [drizzle-kit/src/serializer/singlestoreSchema.ts:89-102](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-kit/src/serializer/singlestoreSchema.ts#L89-L102), [drizzle-kit/src/serializer/gelSchema.ts:216-222](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-kit/src/serializer/gelSchema.ts#L216-L222)

## Related

- [CLI Command Architecture](https://www.doc0.dev/docs/e1b68fed-3c4e-4c95-b2ba-ebf050f78025/technical/migration-toolkit/cli-command-architecture)
- [Database Introspection](https://www.doc0.dev/docs/e1b68fed-3c4e-4c95-b2ba-ebf050f78025/technical/migration-toolkit/database-introspection)


## Sitemap

See the full [sitemap](https://www.doc0.dev/docs/e1b68fed-3c4e-4c95-b2ba-ebf050f78025/llms.txt) for all pages in this wiki.
