Getting Started
Database Drivers
Schema Integrations
Seed Generators
Utilities and Testing
The following files were used as context for generating this wiki page:
Indexes and Constraints represent a critical abstraction layer in Drizzle Kit that bridges the gap between database schema definitions in TypeScript and the concrete implementations in target RDBMS (PostgreSQL, MySQL, Gel). These structures ensure data integrity (constraints) and provide mechanisms for query performance optimization (indexes).
In the context of the Drizzle ecosystem, this subsystem serves as a serializer and introspector. During snapshot generation, it traverses the AnyPgTable objects (imported from drizzle-orm/pg-core), extracts metadata concerning constraints (primary keys, foreign keys, unique constraints, and check constraints) and index definitions, and transforms them into a unified, serializable JSON schema format. This transformation ensures that database changes can be accurately diffed and represented as migration operations.
The design relies on a clear separation between the schema definitions (the runtime TypeScript objects) and the internals or snapshot representations used during diffing. By standardizing these into standardized types defined in pgSchema.ts, Drizzle Kit can perform schema introspection against live databases and compare the results with the defined code, ensuring that index naming collisions or constraint inconsistencies are caught during development.
The subsystem defines schemas using Zod for validation to ensure the integrity of the serialized snapshots. The schema structures act as the "source of truth" for the current state of a database, housing definitions for indexes, foreignKeys, compositePrimaryKeys, uniqueConstraints, and checkConstraints.
Sources: drizzle-kit/src/serializer/pgSchema.ts:139-341
Introspection is the process of querying the live database catalog and reconstructing the schema objects. This allows Drizzle to "see" the database state.
pg_catalog.pg_class.information_schema.table_constraints to identify PRIMARY KEY, UNIQUE, and CHECK constraints.pg_catalog.pg_constraint to retrieve link metadata (which table references what, and associated rules like ON DELETE or ON UPDATE).pg_index and pg_class retrieves index metadata, including access methods (e.g., btree), expressions, and operator classes.Sources: drizzle-kit/src/serializer/pgSerializer.ts:988-1664, drizzle-kit/src/introspect-pg.ts:1230-1652
Sources: drizzle-kit/src/introspect-pg.ts:1230-1652
A key mechanism within generatePgSnapshot is the detection of duplicated constraint names within a schema. This is handled by a local checksInTable or indexesInSchema lookup table.
Caution
If a developer specifies a duplicate index name for different tables within the same schema, Drizzle Kit will detect this via the indexesInSchema lookup and terminate the process with an error, ensuring migration consistency.
The system uses indexName() to automatically generate names for indexes where the user has not provided one, preventing "unnamed" indexes from causing non-deterministic migrations.
Sources: drizzle-kit/src/serializer/pgSerializer.ts:46-48, drizzle-kit/src/serializer/pgSerializer.ts:124-129, drizzle-kit/src/serializer/pgSerializer.ts:456-476
When dealing with expressions in indexes, the serializer requires the user to explicitly name the index, as automatic naming (which relies on column names) is insufficient.
// Example: Index on an expression
index("my_index").using("btree", sql`lower(column_name)`)The system validates the index configuration to ensure that specialized extensions (like pg_vector) have the necessary operator classes specified. The mechanism checks if the column type is a PgVector and iterates through a list of vectorOps to ensure the correct operator class is chosen.
Sources: drizzle-kit/src/serializer/pgSerializer.ts:373-423
Sources: drizzle-kit/src/serializer/pgSerializer.ts:101-113, drizzle-kit/src/serializer/pgSchema.ts:5-46
The schemaToTypeScript function is responsible for converting the serialized snapshot back into TypeScript code. This involves iterating through the table definitions and invoking helper functions like createTableIndexes and createTableFKs.
The mechanism for creating indexes specifically maps the internal Index model to a string statement:
btree) and any specific with options.Sources: drizzle-kit/src/introspect-pg.ts:309-1201
Sources: drizzle-kit/src/introspect-pg.ts:309-565