drizzle-team / drizzle-team/drizzle-orm
[FEATURE]: Clarify misleading field names in generated snapshot JSON (compositePrimaryKeys, column-level primaryKey)
- Dominant language
- TypeScript
- Stars
- 35.8k
- Forks
- 1.6k
- Avg merge
- 2d 7h
- Merged PRs (30d)
- 4
Description
Two field names in the auto-generated `meta/_snapshot.json` produced by
`drizzle-kit generate` read as if they say something different from what
they actually mean. The behavior is correct - generated SQL is right - but the
JSON serialization is confusing for anyone reading or reviewing the snapshot
in code review.
This came up during code review on a TDD-driven schema PR in a project of mine.
The reviewer flagged the snapshot as confusing; the actual answer was
"drizzle-kit's internal data model differs from what the field names suggest."
That answer holds, but it would be better if the field names matched what they
describe.
## Reproduction
Schema:
```ts
import { int, mysqlTable, varchar } from 'drizzle-orm/mysql-core';
export const workspaceRoleTable = mysqlTable('workspaceRole', {
id: int('id', { unsigned: true }).primaryKey().autoincrement(),
role: varchar('role', { length: 64 }).notNull().unique(),
sortKey: int('sortKey', { unsigned: true }).notNull(),
});
```
Run `drizzle-kit generate`. The resulting `meta/0000_snapshot.json` contains:
```json
"id": {
"name": "id",
"type": "int unsigned",
"primaryKey": false,
"notNull": true,
"autoincrement": true
}
```
```json
"compositePrimaryKeys": {
"workspaceRole_id": {
"name": "workspaceRole_id",
"columns": ["id"]
}
}
```
## Two confusing fields
1. `"primaryKey": false` on a column that is in fact the primary key. In
drizzle-kit's internal model the column-level boolean is `false` because
`.primaryKey()` on a column produces a table-level constraint rather than an
inline column attribute. The boolean stays `false` to mark "the PK is
recorded as a constraint, not inline." Defensible internally, but the field
name `primaryKey` naturally reads as the question "is this column the primary
key?" The answer is yes for `id`, but the field reports no.
2. `compositePrimaryKeys` containing a one-column entry. "Composite" is the
wrong English word for a single-column primary key - composite implies
multi-column by definition. The field appears to be a catch-all for
table-level primary-key constraints regardless of column count.
## Suggested fixes
Any of these would help, in rough order of preference:
a. Rename `compositePrimaryKeys` to `tablePrimaryKeys` or just `primaryKeys` in
a future snapshot format version. "Composite" implies multi-column.
b. Set the column-level `primaryKey` boolean to `true` when the column is in
fact the primary key (single-column case), regardless of whether the constraint
is also tracked at the table level. The two views can be consistent without
double-counting in diff logic.
c. If the current shape is intentional and load-bearing, document the field
semantics in the drizzle-kit migrations docs so reviewers do not have to derive
the meaning from internal source.
I worked around this for now by adding a README inside our `drizzle/` directory
that explains the field semantics for future readers, but that is a per-project
mitigation for a tool-side issue.
## Environment
- drizzle-orm: 0.45.2
- drizzle-kit: 0.31.10
- dialect: mysql
- node: 22.x
Thanks for an excellent migration tool. The naming nit is the only friction my
project has hit; the rest of the workflow has been smooth.
Contributor guide
Research direction
Start by reproducing the issue with the supplied MySQL schema and `drizzle-kit generate`, then inspect the generated `meta/_snapshot.json` fields and the drizzle-kit migrations docs. Determine which naming or documentation direction fits the snapshot format and diff behavior; done means the serialized primary-key semantics are no longer misleading and the relevant workflow remains correct.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- databases, tooling
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100