drizzle-team / drizzle-team/drizzle-orm

drizzle-kit 0.31.10: MySQL introspect — `--config` + `--out` triggers false collision; CHECK constraints silently dropped

Open
#5,730 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
35.8k
Forks
1.6k
Avg merge
2d 7h
Merged PRs (30d)
4

Description

Two related issues encountered while running `drizzle-kit introspect` against a MySQL/MariaDB database. Filing together since both surface from the same command path; happy to split if maintainers prefer.

## Environment
- `drizzle-kit`: 0.31.10
- `drizzle-orm`: 0.45.2
- MariaDB 10.11.14 (MySQL protocol)
- Node.js v18.19.1
- Ubuntu 24.04

---

## Bug 1 — `--config` + `--out` triggers false "ambiguous params" exit

### Repro

```bash
pnpm drizzle-kit introspect --config=drizzle.config.ts --out=/tmp/test
```

### Output

```
Invalid input You can't use both --config and other cli options for introspect command
```

Exit code: 1. No files written.

### Expected

Either:
- `--out` overrides the `out` field from the config, or
- this combination is allowed silently — since `out` is also a top-level config key, it shouldn't collide with config presence.

### Root cause (located)

`assertCollisions` (`bin.cjs:10716`) accepts a `remainingKeys` parameter but **never references it inside the function body**. The `pull` command (`bin.cjs:92354`) calls it as:

```js
assertCollisions("introspect", opts, [], ["dialect","driver","out","url","host","port",/* ... */])
```

The intent is clearly that `remainingKeys` lists CLI flags that *are* allowed alongside `--config`. Because the body only checks `whitelist` (which is empty for `pull`), every CLI flag triggers the collision branch.

```js
// bin.cjs:10716 — remainingKeys received but ignored
assertCollisions = (command, options, whitelist, remainingKeys) => {
const { config, ...rest } = options;
let atLeastOneParam = false;
for (const key of Object.keys(rest)) {
if (whitelist.includes(key)) continue; // remainingKeys never consulted
atLeastOneParam = atLeastOneParam || rest[key] !== void 0;
}
// ...
};
```

### Workaround

Either drop `--out` (and rely on `out` from `drizzle.config.ts`), or drop `--config` (and pass full credentials on the CLI).

---

## Bug 2 — MySQL CHECK constraints silently dropped during introspect

### Repro

```sql
CREATE DATABASE drizzle_introspect_repro;
USE drizzle_introspect_repro;
CREATE TABLE t (id INT, val INT, CONSTRAINT chk_val CHECK (val > 0));
```

```bash
pnpm drizzle-kit introspect --dialect=mysql --host=... --database=drizzle_introspect_repro --out=/tmp/out
```

### Output

`schema.ts` is generated; `chk_val` is **absent**. No warning, no error — exit 0.

In our real database, 135 CHECK constraints across 43 tables (mostly `json_valid(col)` patterns) are all silently dropped.

### Expected

Generated `schema.ts` includes the constraint via `.check(...)` (or equivalent), or at minimum prints a warning that CHECK constraints aren't supported by introspect for MySQL.

### Root cause (located)

`fromDatabase` for the MySQL serializer (`bin.cjs:15210`) handles columns, primary keys, foreign keys, indexes, and unique constraints — but contains **no query against `information_schema.CHECK_CONSTRAINTS`** and no code path for emitting `check()` calls. There is a progress spinner that mentions "check constraints fetching" with a count, but no follow-up code uses the count.

### Impact

Any MySQL/MariaDB schema that uses `CHECK` constraints (very common with `json_valid()` for JSON columns) will produce an incomplete `schema.ts`. A round-trip `introspect → push` would drop all such constraints from the database.

---

## How we hit this

We were trying to backfill `_journal.json` after upgrading from `drizzle-kit` 0.21 → 0.31.10. We wanted introspect's snapshot output as a baseline (writing to `/tmp/...` to avoid touching the migrations dir), and that's where Bug 1 surfaced. Bug 2 was discovered while testing whether introspect's snapshot was a faithful reflection of the live schema.

Workaround for our case: derive the baseline from `db:generate`'s internal snapshot rather than `introspect`. But this leaves CHECK constraints out of any future introspect-based tooling.

Happy to test fixes or contribute a PR for Bug 1 if that helps — Bug 1 looks like a one-line fix in `assertCollisions`. Bug 2 is a larger MySQL serializer addition.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.