-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
Feature hasn't been suggested before.
- I have verified this feature I'm about to request hasn't been suggested before.
Describe the enhancement you want to request
Context / prior discussion: #2625
Problem
Drizzle’s Postgres bigint() currently supports mode: 'number' | 'bigint', but not a string mode. Many ecosystems (Discord snowflakes, some external APIs, JSON pipelines) treat 64-bit IDs as strings to avoid precision issues and BigInt JSON pitfalls. Today the only workaround is a customType that converts to/from BigInt, but that breaks/limits ergonomics: you can’t use .generated…AsIdentity() on a customType, and relations are fragile/missing with custom types.
My minimal workaround (works, but limited)
export const bigint = customType<{
data: string;
driverData: string | number | bigint;
}>({
dataType: () => 'bigint',
toDriver: (v) => {
if (typeof v !== 'string' || !/^-?\d+$/.test(v)) {
throw new Error(`Invalid bigint string: ${v}`);
}
return BigInt(v);
},
fromDriver: (v) => (typeof v === 'string' ? v : v.toString()),
});Limitations: cannot combine with .generatedAlwaysAsIdentity() / .generatedByDefaultAsIdentity() and doesn’t integrate cleanly with relations.
Requested feature
Add a third mode for Postgres bigint/bigserial/identity columns:
id: bigint({ mode: 'string' }).primaryKey().generatedAlwaysAsIdentity();What “string mode” should do
- DB type: still
BIGINTin Postgres. - TS types:
select->string,insert->string|undefined(depending on identity). - Driver mapping: automatic
string⇆BigIntconversion similar to the customType above (internally), so users don’t touchBigIntat all. - Works with:
.generatedAlwaysAsIdentity()and (if/when supported).generatedByDefaultAsIdentity(); sequence options remain available. - Relations: first-class support in relations/foreign keys (no “customType” edge cases).
Why this is valuable
- Avoids precision issues and BigInt JSON serialization errors in common stacks.
- Matches how many APIs represent 64-bit IDs (strings).
- Keeps the great DX of identity columns and relations—without customType foot-guns
Backward compatibility
- Non-breaking: add
stringalongside existingnumber|bigint; current behavior stays default. - Docs: a short note in PostgreSQL -> bigint explaining when to pick
string(JSON/web APIs), vsnumber(≤ 2^53), vsbigint(nativebigint).
Thanks! This would remove a common friction point when integrating with external APIs while preserving Drizzle’s type-safety and identity ergonomics.