@netkasystem/drizzle-db-patch
v0.1.3
Published
Generate SQL patches by diffing Drizzle schema against a live PostgreSQL database, plus a seed dry-runner that captures INSERT statements without touching the DB.
Downloads
26
Readme
@netka-entrust/drizzle-db-patch
Generate SQL patches for PostgreSQL databases backed by Drizzle ORM:
generate— diff a Drizzle schema module against a live database and emit a SQL patch (CREATE TABLE, ADD COLUMN, CREATE INDEX, ADD FOREIGN KEY, ADD UNIQUE, plus commented DROPs for orphans). Read-only against the target DB.seed— dry-run a seed orchestrator and capture every emitted INSERT as inline SQL. The DB client is stubbed; no real connection is opened.
Peer-depends on drizzle-orm (>= 0.30) and postgres (>= 3.4). Node ≥ 20.
Install
pnpm add -D @netkasystem/drizzle-db-patchPublished as a public package on npmjs.com — no authentication required.
CLI
generate — schema vs live DB
DATABASE_URL="postgres://user:pass@host:5432/db" \
pnpm drizzle-db-patch generate \
--schema ./src/db/schema \
--out ./scripts/db-patch.sqlOptions:
| Flag | Default | Description |
| ---------------- | --------------- | ----------------------------------------------------------------------------------------------------------- |
| --schema | (required) | Path to a module that exports the Drizzle schema (typically a barrel file that re-exports every pgTable). |
| --database-url | $DATABASE_URL | Postgres connection URL. Read-only access is sufficient. |
| --out | db-patch.sql | Output file. |
Output sections (each wrapped in BEGIN/COMMIT):
- Missing tables —
CREATE TABLE IF NOT EXISTS - Missing columns —
ALTER TABLE ADD COLUMN IF NOT EXISTS - Orphan tables — commented
DROP TABLE(manual review) - Orphan columns — commented
ALTER TABLE DROP COLUMN(manual review) - Missing indexes —
CREATE INDEX IF NOT EXISTS - Missing foreign keys —
ALTER TABLE ADD CONSTRAINT ... FOREIGN KEY - Missing unique constraints —
ALTER TABLE ADD CONSTRAINT ... UNIQUE
seed — dry-run a seed orchestrator
The seed command needs an entrypoint module that wires your application's DB client to the stub provided by this package. Create a file like scripts/seed-patch-entry.ts:
import type { GenerateSeedPatchOptions } from "@netkasystem/drizzle-db-patch";
const opts: GenerateSeedPatchOptions = {
installStub: async (stub) => {
// Replace the real postgres-js client with the stub. The exact wiring
// depends on how your app exposes the client.
const dbModule = (await import("@/db")) as {
db: { session: { client: unknown } };
};
dbModule.db.session.client = stub;
},
runSeed: async () => {
// Intercept process.exit so the seed runner doesn't kill our process
// before we write the patch.
const origExit = process.exit.bind(process);
let exited = false;
(process as unknown as { exit: (code?: number) => void }).exit = (() => {
exited = true;
}) as never;
try {
await import("@/db/seed/seed");
const start = Date.now();
while (!exited) {
if (Date.now() - start > 300_000) {
throw new Error("Timed out waiting for seed to finish (5 min).");
}
await new Promise((r) => setTimeout(r, 100));
}
} finally {
process.exit = origExit;
}
},
header: ["Source: src/db/seed (dry-run, no DB connection)"],
};
export default opts;Then run:
pnpm drizzle-db-patch seed \
--entry ./scripts/seed-patch-entry.ts \
--out ./scripts/seed-patch.sqlThe CLI loads the entry module, calls installStub(stub), runs runSeed(), and writes captured INSERTs to --out. SELECTs are answered from rows inserted earlier in the same run (best-effort), so seeds that chain INSERT ... RETURNING -> SELECT can usually complete.
Programmatic API
import {
generateDbPatch,
generateSeedPatch,
} from "@netkasystem/drizzle-db-patch";
import * as schema from "./src/db/schema";
const { sql, stats } = await generateDbPatch({
schema,
databaseUrl: process.env.DATABASE_URL!,
});See src/index.ts for full type definitions.
Publishing (manual)
The package is not auto-published. Bump the version and publish from a local workstation:
cd packages/drizzle-db-patch
# 1. Bump version
npm version patch # or minor / major
# 2. Build
pnpm build
# 3. Login to npmjs.com (once per machine)
npm login
# 4. Publish
npm publish --registry=https://registry.npmjs.orgThe package's publishConfig.registry points at https://registry.npmjs.org. The --registry flag overrides any scope mapping in your global ~/.npmrc (e.g. if @netkasystem is mapped to GitHub Packages there).
After publishing, commit the version bump:
git add packages/drizzle-db-patch/package.json
git commit -m "chore(drizzle-db-patch): publish vX.Y.Z"