---
title: "Column Types"
description: "Column Types in Drizzle provide a robust, type-safe interface for mapping database schemas to TypeScript objects. By defining a set of core builders and runtime definitions, Drizzle ensures that ev..."
last_updated: "2026-07-02T09:35:18.60962+00:00"
canonical_url: "https://www.doc0.app/docs/e1b68fed-3c4e-4c95-b2ba-ebf050f78025/technical/database-schema/column-types"
---

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

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

- [drizzle-kit/src/introspect-mysql.ts](https://github.com/blade47/drizzle-orm/blob/main/drizzle-kit/src/introspect-mysql.ts)
- [drizzle-kit/src/introspect-gel.ts](https://github.com/blade47/drizzle-orm/blob/main/drizzle-kit/src/introspect-gel.ts)
- [drizzle-kit/src/introspect-singlestore.ts](https://github.com/blade47/drizzle-orm/blob/main/drizzle-kit/src/introspect-singlestore.ts)
- [drizzle-orm/src/pg-core/columns/common.ts](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/pg-core/columns/common.ts)
- [drizzle-orm/src/pg-core/columns/numeric.ts](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/pg-core/columns/numeric.ts)
- [drizzle-orm/src/singlestore-core/columns/decimal.ts](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/singlestore-core/columns/decimal.ts)
- [drizzle-orm/src/column-builder.ts](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/column-builder.ts)
- [drizzle-orm/src/sqlite-core/columns/numeric.ts](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/sqlite-core/columns/numeric.ts)
- [drizzle-orm/src/sqlite-core/columns/blob.ts](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/sqlite-core/columns/blob.ts)
- [drizzle-orm/src/sqlite-core/columns/integer.ts](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/sqlite-core/columns/integer.ts)
- [drizzle-orm/src/singlestore-core/columns/datetime.ts](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/singlestore-core/columns/datetime.ts)
- [drizzle-orm/src/singlestore-core/columns/custom.ts](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/singlestore-core/columns/custom.ts)
- [drizzle-orm/src/gel-core/columns/custom.ts](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/gel-core/columns/custom.ts)
- [drizzle-orm/src/sqlite-core/columns/custom.ts](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/sqlite-core/columns/custom.ts)
</details>

Column Types in Drizzle provide a robust, type-safe interface for mapping database schemas to TypeScript objects. By defining a set of core builders and runtime definitions, Drizzle ensures that every column in a table can be accurately queried, validated, and serialized to the underlying database dialect, whether it is PostgreSQL, MySQL, SQLite, Gel, or SingleStore.

The system is architected around a separation between the build phase and the runtime phase. Builder classes, such as those derived from `PgColumnBuilder` or `SQLiteColumnBuilder`, manage configurations—such as nullability, default values, and primary key constraints—during the schema definition phase. When a table is built, these builders transition into runtime column instances, which hold the logic for data transformation between the driver's raw output and the application's domain types.

Design decisions within this subsystem prioritize type inference and dialect-specific abstraction. Builders use generics to track data types (e.g., `'string'`, `'number'`, `'boolean'`), while the column classes handle dialect-specific serialization quirks, such as different integer representations or JSON/Blob handling. This layered design allows Drizzle to expose a unified API surface while maintaining the performance and flexibility required for cross-dialect database management.

## Core Builder Infrastructure

The `PgColumnBuilder` or `SQLiteColumnBuilder` classes (and their equivalents) are the roots for column definitions in their respective dialects. Their primary purpose is to collect configuration metadata before a table is fully realized. They implement the chainable API used in table definitions, such as `.notNull()`, `.default()`, and `.primaryKey()`.

Internally, the `config` object acts as a state container. When you call `.notNull()`, the builder simply sets `this.config.notNull = true` and returns `this` cast to a specific type, ensuring the TypeScript compiler reflects this state change for subsequent chain calls.

Sources: [drizzle-orm/src/pg-core/columns/common.ts:38-43](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/pg-core/columns/common.ts#L38-L43), [drizzle-orm/src/sqlite-core/columns/common.ts:6](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/sqlite-core/columns/common.ts#L6)

## Dialect-Specific Column Implementations

While building interfaces share commonality, actual data type implementation is split by dialect. For example, `PgNumericBuilder` and `SQLiteNumericBuilder` both offer numeric column support but handle the mapping logic to their respective driver's outputs differently.

In the `PgNumeric` implementation, the `mapFromDriverValue` function is designed to handle `unknown` inputs, converting them to `string` if they are not already, ensuring consistent behavior despite database variability. Conversely, the `SQLiteNumericNumber` implementation specifically maps its inputs to `number` type, demonstrating how builders and runtime definitions tailor the interface based on the requested `mode`.

Sources: [drizzle-orm/src/pg-core/columns/numeric.ts:40-67](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/pg-core/columns/numeric.ts#L40-L67), [drizzle-orm/src/sqlite-core/columns/numeric.ts:37-49](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/sqlite-core/columns/numeric.ts#L37-L49), [drizzle-orm/src/sqlite-core/columns/numeric.ts:80-94](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/sqlite-core/columns/numeric.ts#L80-L94)

## Custom Type Support

Drizzle provides a `customType` function for each dialect to support proprietary or complex database types that are not explicitly covered by the core library. This subsystem allows developers to specify the underlying SQL data type via a `dataType` function and provide custom `toDriver` and `fromDriver` mapping functions.

When a column is defined via `customType`, the builder instance (e.g., `SingleStoreCustomColumnBuilder` or `SQLiteCustomColumnBuilder`) holds the configuration, while the resulting column class instance encapsulates the mapping logic. This architecture prevents core code from needing awareness of every possible niche database type while still providing seamless integration.

Sources: [drizzle-orm/src/singlestore-core/columns/custom.ts:26-59](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/singlestore-core/columns/custom.ts#L26-L59), [drizzle-orm/src/sqlite-core/columns/custom.ts:25-58](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/sqlite-core/columns/custom.ts#L25-L58)

## Lifecycle and Initialization Flow

The transition from a definition to a concrete database object involves a specific initialization sequence. When a table is declared, the framework instantiates the builder classes. The `build()` method is then invoked, which consumes the `config` object from the builder and initializes the runtime column class.

For example, when constructing an array column in PostgreSQL:
1. `PgArrayBuilder` is initialized with a base builder.
2. The user calls `.build(table)`.
3. `PgArrayBuilder` instantiates the base column and passes it to the `PgArray` constructor.
4. The `PgArray` constructor sets the array-specific SQL type, such as `integer[]`.

Sources: [drizzle-orm/src/pg-core/columns/common.ts:260-307](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/pg-core/columns/common.ts#L260-L307)

## Serialization and Introspection Logic

Drizzle Kit performs introspection to convert raw database schema data back into Drizzle ORM TypeScript code. This involves mapping raw column types back to Drizzle function calls.

The `schemaToTypeScript` function in the MySQL introspector, for instance, iterates over table columns, patches type strings using a lookup table (`importsPatch`), and then dispatches the result to a `column()` function. This function acts as a factory, matching the string type to a constructor for the correct builder, and generating the necessary `.default()` or `.primaryKey()` chain calls.

Sources: [drizzle-kit/src/introspect-mysql.ts:133-195](https://github.com/blade47/drizzle-orm/blob/main/drizzle-kit/src/introspect-mysql.ts#L133-L195), [drizzle-kit/src/introspect-mysql.ts:386-416](https://github.com/blade47/drizzle-orm/blob/main/drizzle-kit/src/introspect-mysql.ts#L386-L416)

> [!NOTE]
> When introspecting columns, the framework maps "int unsigned" types to standard integer builders and applies an `{ unsigned: true }` parameter in the generated code.

## Data Mapping Mechanisms

Each column type contains logic to bridge the gap between driver data and application data. `mapFromDriverValue` and `mapToDriverValue` are the primary lifecycle hooks for this conversion.

For instance, the `SQLiteBlobJson` column type defines how it handles raw binary data:
```typescript
override mapFromDriverValue(value: Buffer | Uint8Array | ArrayBuffer): T['data'] {
    // ... decoding logic
    return JSON.parse(buf.toString('utf8'));
}
```
This is critical because SQLite doesn't have a native JSON type; it forces developers to store JSON objects in `blob` or `text` columns, and this mapping function abstracts that limitation entirely away from the developer.

Sources: [drizzle-orm/src/sqlite-core/columns/blob.ts:100-114](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/sqlite-core/columns/blob.ts#L100-L114)

## Design Trade-offs

| Design Choice | Benefit | Cost |
| :--- | :--- | :--- |
| **Separate Builder Class** | Decouples runtime logic from schema configuration. | Requires double instantiation (builder → column instance). |
| **Dialect-specific Builders** | Allows for exact SQL feature mapping per database. | Increased codebase size through specialized classes. |
| **Type-safe Mapper** | Prevents runtime data corruption at the boundary. | Performance overhead during heavy read/write operations. |

Sources: [drizzle-orm/src/column-builder.ts:185-317](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/column-builder.ts#L185-L317), [drizzle-orm/src/pg-core/columns/numeric.ts:17-38](https://github.com/blade47/drizzle-orm/blob/main/drizzle-orm/src/pg-core/columns/numeric.ts#L17-L38)

## Related

- [Schema Declarations](https://www.doc0.app/docs/e1b68fed-3c4e-4c95-b2ba-ebf050f78025/technical/database-schema/schema-declarations)


## Sitemap

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