TypeScript · SQL

Drizzle ORM migrations, drawn as a database diagram

The SQL files drizzle-kit generate produces, together with the meta/_journal.json journal. SchemaDrawer runs drizzle-orm 0.45 with drizzle-kit 0.31 output against a throw-away database of the engine you choose and returns an SVG of the schema it produces.

What to upload

Upload the folder drizzle-kit generate wrote: the numbered .sql files and the meta/ directory with _journal.json. There must be exactly one journal in the upload, and every SQL file next to it must be listed in the journal, otherwise the upload is refused rather than drawn incomplete. Snapshot files may come along.

The sample below is the PetClinic schema written for Drizzle ORM, one of the sets SchemaDrawer's own tests draw on every engine:

drizzle/
├── meta/
│   └── _journal.json
├── 0000_create_owners_and_pets.sql
├── 0001_create_vets.sql
└── 0002_create_visits.sql

Formats

SQL files plus meta/_journal.json.

How it runs

migrate() from drizzle-orm with a configuration generated for the chosen engine. The database is a fresh PostgreSQL, MySQL, MariaDB, SQL Server, Oracle or SQLite container in the version you ask for; nothing of yours is touched.

Databases you can draw Drizzle ORM on

PostgreSQL 10, 11, 12, 13, 14, 15, 16, 17, 18 MySQL 8.0, 8.4, 9 MariaDB 10.6, 11.4, 11.8, 12 SQL Server Oracle SQLite

Not offered for Drizzle ORM: SQL Server, Oracle. The tool ships no driver for them, so nothing could run.

At a glance

Runs
drizzle-orm 0.45 with drizzle-kit 0.31 output, applied through drizzle-orm's migrate()
API value
migrationType=DRIZZLE
Engines
4 of 6: PostgreSQL, MySQL, MariaDB, SQLite
Output
SVG diagram with tables, columns and types, primary and foreign keys
Price
Free today; enterprise plans are coming
Example

The PetClinic schema in Drizzle ORM

Owners, pets, types, vets, specialties and visits: the same seven tables every sample set on this site creates. These are the exact files the tests upload.

CREATE TABLE owners
(
    id         INT          NOT NULL,
    first_name VARCHAR(50)  NOT NULL,
    last_name  VARCHAR(50)  NOT NULL,
    address    VARCHAR(255),
    city       VARCHAR(80),
    telephone  VARCHAR(20),
    CONSTRAINT pk_owners PRIMARY KEY (id)
);
--> statement-breakpoint
CREATE TABLE types
(
    id   INT         NOT NULL,
    name VARCHAR(80) NOT NULL,
    CONSTRAINT pk_types PRIMARY KEY (id)
);
--> statement-breakpoint
CREATE TABLE pets
(
    id         INT         NOT NULL,
    name       VARCHAR(50) NOT NULL,
    birth_date DATE,
    type_id    INT         NOT NULL,
    owner_id   INT         NOT NULL,
    CONSTRAINT pk_pets PRIMARY KEY (id),
    CONSTRAINT fk_pets_types FOREIGN KEY (type_id) REFERENCES types (id),
    CONSTRAINT fk_pets_owners FOREIGN KEY (owner_id) REFERENCES owners (id)
);
CREATE TABLE vets
(
    id         INT         NOT NULL,
    first_name VARCHAR(50) NOT NULL,
    last_name  VARCHAR(50) NOT NULL,
    CONSTRAINT pk_vets PRIMARY KEY (id)
);
--> statement-breakpoint
CREATE TABLE specialties
(
    id   INT         NOT NULL,
    name VARCHAR(80) NOT NULL,
    CONSTRAINT pk_specialties PRIMARY KEY (id)
);
--> statement-breakpoint
CREATE TABLE vet_specialties
(
    vet_id       INT NOT NULL,
    specialty_id INT NOT NULL,
    CONSTRAINT pk_vet_specialties PRIMARY KEY (vet_id, specialty_id),
    CONSTRAINT fk_vet_specialties_vets FOREIGN KEY (vet_id) REFERENCES vets (id),
    CONSTRAINT fk_vet_specialties_specialties FOREIGN KEY (specialty_id) REFERENCES specialties (id)
);
CREATE TABLE visits
(
    id          INT NOT NULL,
    pet_id      INT NOT NULL,
    visit_date  DATE,
    description VARCHAR(255),
    CONSTRAINT pk_visits PRIMARY KEY (id),
    CONSTRAINT fk_visits_pets FOREIGN KEY (pet_id) REFERENCES pets (id)
);
{
  "version": "7",
  "dialect": "postgresql",
  "entries": [
    {
      "idx": 0,
      "version": "7",
      "when": 1758400000000,
      "tag": "0000_create_owners_and_pets",
      "breakpoints": true
    },
    {
      "idx": 1,
      "version": "7",
      "when": 1758400001000,
      "tag": "0001_create_vets",
      "breakpoints": true
    },
    {
      "idx": 2,
      "version": "7",
      "when": 1758400002000,
      "tag": "0002_create_visits",
      "breakpoints": true
    }
  ]
}
diagram.svg
ER diagram of the PetClinic schema drawn by SchemaDrawer: owners, pets, types, vets, specialties, vet_specialties and visits with their columns, primary keys and foreign keys

Every variant of the sample produces these seven tables. This diagram was drawn from the Flyway variant on PostgreSQL 18; on MySQL the types read INT and VARCHAR, on Oracle the names are upper case.

Run it

Draw your Drizzle ORM migrations

One multipart request queues the drawing; poll the job until it succeeds and download the SVG. Or let the GitHub Action do it and open a pull request with the diagram.

With curl

curl -X POST https://schemadrawer.com/api/v1/drawing \
  -H "Request-Id: $(uuidgen)" \
  -F "userId=5f0c1d2e-3a4b-4c5d-8e6f-7a8b9c0d1e2f" \
  -F "migrationType=DRIZZLE" \
  -F "databaseType=POSTGRESQL" \
  -F "version=18" \
  -F "files=@drizzle/0000_create_owners_and_pets.sql" \
  -F "files=@drizzle/0001_create_vets.sql" \
  -F "files=@drizzle/0002_create_visits.sql" \
  -F "files=@drizzle/meta/_journal.json;filename=meta/_journal.json"
# {"jobId":"0b6e2f4c-8d1a-4c3e-9f7a-2a5b6c7d8e9f"}

Then poll GET https://schemadrawer.com/api/v1/drawing/{jobId} until status is SUCCESS and fetch diagramUrl. Details in the getting started guide and the API reference.

With the GitHub Action

- uses: schemadrawercom/action@v1
  with:
    sql-directory: drizzle
    output-path: docs/schema-diagram.svg
    migration-type: DRIZZLE
    database-type: POSTGRESQL
    database-version: '18'
    github-token: ${{ secrets.GITHUB_TOKEN }}

The action uploads the directory, waits for the diagram and opens a pull request with the SVG. See the action reference.

Good to know

  • The SQL runs verbatim and drizzle-kit quotes identifiers for one dialect, so draw on the engine you generated the migrations for.
  • The __drizzle_migrations table is left out of the diagram.
  • Drizzle has no SQL Server or Oracle migrator, so those engines are not offered for it.
  • A drawing may take up to 120 seconds; a job that waits in the queue longer than 10 minutes fails rather than draws. Uploads of up to 100 MB and 2000 files are accepted.
From the blog

Reading about Drizzle ORM and migrations

Draw your Drizzle ORM schema now

Upload the migration directory, get an SVG back. Free while we build it.