If you've ever tried to explain your database structure to a teammate and ended up drawing boxes on a whiteboard, you already know the pain. Database schema diagrams created by hand go stale fast, and nobody wants to maintain them. Creating a database schema diagram with code fixes that your diagram stays in sync with your actual database, lives in version control, and updates automatically when your schema changes. This approach saves time, reduces errors, and keeps your documentation honest.

What does it mean to create a database schema diagram with code?

Instead of dragging and dropping tables in a visual editor, you write code or a configuration file that describes your database tables, columns, and relationships. A tool then reads that description and generates a visual diagram for you. The code acts as the single source of truth. When your schema changes, you update the code, and the diagram regenerates.

This is different from reverse-engineering a live database (though that's another valid approach). Writing schema as code means you're defining the structure before or alongside your migrations, keeping documentation and implementation tightly coupled.

Why would you generate diagrams from code instead of using a visual tool?

Visual diagramming tools like dbdiagram.io or Lucidchart work fine for quick sketches. But they create a maintenance problem. Someone has to remember to update the diagram every time the schema changes. In practice, that rarely happens.

When your schema diagram is generated from code, you get several advantages:

  • Version control your diagram definition lives in Git alongside your application code. You can see exactly what changed and when.
  • Automation regenerate diagrams as part of your CI/CD pipeline or as a pre-commit hook.
  • Accuracy the diagram reflects the actual schema definition, not someone's memory of it.
  • Collaboration teammates can review schema changes in pull requests, and the diagram updates with them.

If you're working on a relational database with many tables and foreign key relationships, this approach becomes especially valuable as your project grows.

What tools can generate database diagrams from code?

Several tools accept a text-based schema definition and output a diagram. Here are the most common options:

  • DBML (Database Markup Language) a simple, readable syntax designed specifically for defining database schemas. Tools like dbdiagram.io parse DBML and render diagrams instantly.
  • PlantUML a general-purpose diagramming language that supports entity-relationship diagrams. You write a text file, and PlantUML generates an image.
  • SchemaCrawler a Java-based tool that connects to a live database and generates diagrams. Good for reverse-engineering existing schemas.
  • ERAlchemy a Python tool that generates ER diagrams from SQLAlchemy models or live databases. Outputs to PDF, PNG, or other formats.
  • Mermaid.js a JavaScript-based diagramming library that supports ER diagrams and renders in Markdown, making it popular for documentation sites.

Each tool has different strengths. For a deeper comparison of available options, check out our breakdown of tools for generating database schema diagrams from code.

How do you create a schema diagram using DBML?

DBML is one of the easiest ways to get started. The syntax reads almost like plain English. Here's a basic example:

Table users {
  id integer [primary key]
  username varchar
  email varchar
  created_at timestamp
}

Table posts {
  id integer [primary key]
  user_id integer [ref: > users.id]
  title varchar
  body text
  published_at timestamp
}

Table comments {
  id integer [primary key]
  post_id integer [ref: > posts.id]
  user_id integer [ref: > users.id]
  body text
  created_at timestamp
}

Paste this into dbdiagram.io, and you'll see three tables with their relationships rendered as a clean ER diagram. The [ref: >] notation defines foreign key relationships, and the tool draws the connecting lines automatically.

For more relational database examples with different relationship types (one-to-many, many-to-many, one-to-one), see our relational database schema diagram code examples.

How do you generate a schema diagram using Python and ERAlchemy?

If your project uses SQLAlchemy, ERAlchemy can read your models and produce a diagram. Here's the basic workflow:

  1. Install ERAlchemy: pip install eralchemy
  2. If you have SQLAlchemy models defined, ERAlchemy can introspect them directly.
  3. Run the command: eralchemy -i sqlite:///mydb.sqlite -o diagram.png
  4. Open the generated diagram.png file.

You can also use it with PostgreSQL, MySQL, or any database SQLAlchemy supports. The tool reads the schema from the live database and generates the diagram no manual markup needed.

How do you create a schema diagram with Mermaid.js?

Mermaid.js has gained popularity because it renders diagrams directly in Markdown files, GitHub READMEs, and documentation sites. Here's a simple example:

erDiagram
  USERS ||--o{ POSTS : "writes"
  POSTS ||--o{ COMMENTS : "has"
  USERS ||--o{ COMMENTS : "writes"

  USERS {
    int id PK
    string username
    string email
  }

  POSTS {
    int id PK
    int user_id FK
    string title
    text body
  }

  COMMENTS {
    int id PK
    int post_id FK
    int user_id FK
    text body
  }

This renders a visual ER diagram showing the three tables and their relationships. Mermaid supports ||--o{ (one-to-many), ||--|| (one-to-one), and other cardinality notations.

What are common mistakes when creating schema diagrams from code?

A few pitfalls trip people up regularly:

  • Not including all relationships. If you define tables but forget foreign key references, your diagram will show isolated boxes with no connecting lines. Always define your constraints.
  • Letting the code go stale. The whole point is keeping diagrams in sync. If you change your database schema but don't update the diagram code, you've recreated the same problem you were trying to solve.
  • Over-complicating the diagram. Including every column in every table on a single diagram creates visual clutter. For large schemas, consider splitting into logical groups one diagram per domain or module.
  • Ignoring naming conventions. Inconsistent naming between your diagram code and your actual database makes the diagram misleading. Use the same naming patterns you use in migrations.
  • Skipping indexes and constraints. Primary keys and foreign keys are essential, but unique constraints and indexes also affect how your database behaves. Include them when relevant.

How do you fit schema diagram generation into your workflow?

The best approach depends on your team and project size. Here are three practical setups:

For small projects: Keep a DBML or Mermaid file in your repository root. Manually update it when you change the schema. Most editors have syntax highlighting for these formats, so the files are easy to maintain.

For medium projects: Add a script to your Makefile or package.json that regenerates the diagram. Run it as part of your pull request checklist. Something like npm run generate-diagram or make diagram.

For larger teams: Integrate diagram generation into CI/CD. When a migration runs, the pipeline generates a new diagram and commits it to the docs folder. Tools like SchemaCrawler can connect to a test database and produce an up-to-date diagram on every build.

Should you generate diagrams from your ORM models or your database?

Both approaches work, but they serve slightly different needs:

From ORM models (code-first): Your diagram reflects what your application intends the schema to look like. This is useful during development, before migrations have run. Tools like ERAlchemy (with SQLAlchemy) or Django's graph_models management command work this way.

From a live database (database-first): Your diagram reflects what the schema actually looks like, including any manual changes or migration drift. SchemaCrawler and ERAlchemy both support this mode.

For most teams, generating from the live database is more reliable because it catches discrepancies between your ORM definitions and the actual database state.

Quick checklist: getting your first schema diagram from code

  • Pick your format DBML for simplicity, Mermaid for Markdown integration, PlantUML for advanced customization, or ERAlchemy for Python projects.
  • Define your tables include table names, column names, data types, and primary keys.
  • Add relationships use foreign key references to connect tables. Don't skip many-to-many junction tables.
  • Generate the diagram use the tool's CLI or web interface to render your output.
  • Commit the source file check the diagram definition into version control alongside your migration files.
  • Automate regeneration add a script or CI step so the diagram stays current as your schema evolves.

Start with a single DBML file covering your core tables. Once you see how much time it saves during code reviews and onboarding, you'll naturally expand the practice to your full schema. For a full walkthrough on setting up this process, visit our guide on creating database schema diagrams with code.