ErdDocs

SQLAlchemy models to ER diagram

Paste your models and get the ER diagram of the tables they map to, with table names from __tablename__ and relations from ForeignKey. No pip install, no Graphviz binary, no database connection. The file is read in your browser and never uploaded.

Your schema

The example mixes both declaration styles on purpose. Paste your own models.py over it.

Both styles, including a file that mixes them

SQLAlchemy has two ways to declare a column and both are everywhere: the classic assignment and the 2.0 annotated form. A codebase part-way through a migration contains both, often in the same file. The example above does exactly that: four classic models and one written the new way.

  • Classic style. email = Column(String(160), nullable=False, unique=True). Type, flags and comment all live in the call.
  • 2.0 style. notes: Mapped[Optional[str]] = mapped_column(Text). The annotation carries the nullability, so Optional is read as a nullable column even though nothing says nullable=True.

No install, and the file does not have to import

ErdDocs reads the models as text in a browser tab, so there is nothing to install and no Graphviz to find. eralchemy is a Python package that wants a system Graphviz binary to render anything. That is a large ask on a machine you do not administer, or when the models arrived as an attachment and you just want to see their shape.

ErdDocs does not execute your code either. The models are read as text, so a file that would not import still draws. That covers a missing dependency, a half-finished refactor, or a snippet copied out of a review.

What ends up in the diagram

  • Tables, not classes. __tablename__ wins, so class Company is drawn as companies.
  • Real relations. ForeignKey("jobs.id") becomes a solid line. relationship() is not a column and is not drawn as one. The foreign key column next to it is what the database actually has.
  • The properties a reviewer asks about: primary keys, autoincrement, nullability, unique constraints, defaults and server_default, with comment= text becoming the description in the data dictionary.

FAQ

Does it read the 2.0 style as well as the classic one?

Both, including a file that mixes them. The classic id = Column(Integer, primary_key=True) and the 2.0 id: Mapped[int] = mapped_column(primary_key=True) are read the same way. In the 2.0 style, the annotation fills in whatever the call leaves out. Mapped[Optional[str]] means the column is nullable even when nullable= is not written.

Do I need Graphviz or pip install anything?

No. ErdDocs reads the models as text you paste into a browser tab. There is no pip, no PATH and no binary. eralchemy is a Python package that also needs a system Graphviz binary on the PATH to render. That is awkward on a locked-down laptop, or when someone else handed you models.py.

What does it take from the models?

It takes __tablename__ as the table name and each column with the SQL type the model asks for. It also reads primary keys, autoincrement, nullable and unique flags, server_default and default values, comment= text as the description, and ForeignKey("table.column") as a real relation. relationship() is not a column and is not drawn as one. The foreign key column beside it is what the database has.

What about models spread over many files?

Paste them one after another into the same panel. ErdDocs reads classes, not modules, so several files concatenated behave exactly like one file. ErdDocs never executes your code, so there are no imports to arrange. The models are read as text, so a file that would not import still produces a diagram.

Is it free?

Drawing and exporting the picture are free, no account, for schemas up to 25 tables. $9 once lifts the limit and unlocks the data dictionary. That is the document form, with every column, type, default and index listed.

Related