Repository navigation
Releases: devsuit-berlin/erdify
Release list
v0.14.1
erdify 0.14.1 — a fix for django-ninja ModelSchema, and the new documentation image.
Fixed
- erdify now recognises ninja-style
ModelSchemaclasses — those taking their
fields from a Django model via an innerMeta(django-ninja) orConfig
(ninja-schema) — and skips them with an explanatory warning instead of
drawing an entity with no fields. NamingModelSchemavia--base-classes
previously produced an empty box beside the real table, which was worse than
no support at all. Detection is narrow: only an innerMeta/Configthat
assignsmodelcounts, so an ordinary Pydantic model with a nested config
class and Django's ownclass Metaare both untouched. Resolving those
schemas properly remains open in
#171. docs/examples/frameworks.svgis well-formed XML again. Its header comment
contained a command-line flag, and XML comments may not contain a double
hyphen, so the file failed to parse — harmless for the site, which serves the
PNG, but the file documented as "the editable source" would not open in a
browser or vector editor.- The image footer reads "and raw SQL DDL" rather than listing it as a sixth
bullet. The headline counts five frameworks; SQL DDL is an input format, and
the flat list made the two numbers look like they disagreed.
Changed
- The README and the documentation home page now open with a "five frameworks,
one diagram" image — the sameUser/Orderschema written in SQLModel,
SQLAlchemy, Django, Pydantic and dataclasses, converging on the ERD they all
produce. The previous image was the bare ERD under a caption claiming five
frameworks, which the picture itself never showed. The snippets are taken
from the runnable examples indocs/examples/, and it is drawn in the devsuit
brand palette.docs/examples/frameworks.svgis the editable source; the
now-unreferenceddocs/examples/erd.pngis removed.
Install: pip install erdify · Docs: https://erdify.devsuit.io/ · Full diff: v0.14.0...v0.14.1
v0.14.0
erdify 0.14.0 — ER diagrams for django-ninja schemas, and an honest comparison.
Added
--base-classes NAME [NAME ...](andbase_classesin[tool.erdify]) names
extra base classes to treat as Pydantic models. Pydantic detection resolves
ancestors only across the scanned files, so a base defined in an installed
package —ninja.Schemafrom django-ninja — or in an internal library that
--includedoes not match was unresolvable, and every subclass of it was
silently skipped. Both the bare (Schema) and qualified (ninja.Schema)
forms are matched, and intermediate bases defined in scanned files still
resolve transitively. Partially addresses
#171; the
ModelSchemavariants, whose fields come from an innerMeta/Config
rather than the class body, remain unsupported.
Fixed
- The comparison page and the README comparison table were wrong about two
rows. Both claimed no alternative ships a Markdown-injection or a CI
drift-check feature; paracelsus ships
both, along with[tool.paracelsus]configuration and Mermaid output. It is
now a column in the comparison table and a named entry under "when to use
something else": it reaches models by importing them (--import-module), so
it sees the fully-resolved metadata an AST scan cannot, and for a
single-SQLAlchemy project that accuracy may be worth more than erdify's
independence.
Install: pip install erdify · Docs: https://erdify.devsuit.io/ · Full diff: v0.13.0...v0.14.0
v0.13.0
erdify 0.13.0 — one ERD generator for every Python schema in your repository.
Warning
Breaking: a run that finds no tables now exits 1 instead of 0 and writes nothing. Pass --allow-empty (or set allow_empty = true under [tool.erdify]) to restore the previous behavior. Details below.
Changed — breaking
-
A run that finds no tables now exits
1instead of0, and writes
nothing. Up to 0.12.3 it warned, wrote a structurally valid but empty
diagram, and exited0— so a CI job that commits the regenerated ERD
silently replaced a good diagram with an empty one whenever--include
stopped matching, which a rename or a moved package is enough to cause. The
overwhelmingly likely cause of zero entities is a misconfiguration, so that
is now an error.Failing before generation means an existing output file is left untouched.
If an empty schema is a legitimate outcome for your project — everything
filtered out by--exclude, a--sourcesfilter that matches nothing, a
schema mid-migration — pass--allow-emptyor setallow_empty = trueunder
[tool.erdify]. That restores the previous behavior exactly.
Added
- New documentation page Comparison — erdify next to eralchemy,
sqlalchemy-schemadisplay, erdantic,django-extensions graph_modelsand
DBML/dbdiagram, on the axes that actually differ (live connection, importing
your code, frameworks covered, runtime dependencies, output formats, CI drift
gate), including where each alternative is the better choice. - New documentation page Python Parsing Limitations — the Python-side
counterpart to the SQL frontend's "Deferred / Not Supported" table: what the
AST parser cannot see (runtime-constructed models, non-literal
__tablename__,__table_args__, composite foreign keys, foreign keys inside
sa_column, unannotatedrelationship()assignments) and what to do instead. - New documentation page Troubleshooting — symptom-first fixes for models
not being found, too many entities, missing relationships and missing keys on
Pydantic/dataclass models. - Every documentation page now carries its own
descriptionfrontmatter, so
each page gets its own search-engine snippet and social-card subtitle instead
of repeatingsite_description. --allow-empty(andallow_emptyin[tool.erdify]) opts back in to the
pre-0.13.0 behavior for an empty result: warn, write the empty diagram, exit
0. See the breaking change below.- erdify now ships
.pre-commit-hooks.yaml, so it can be used as a pre-commit
repository instead of arepo: local/language: systemhook that requires
erdify to be installed in the consumer's environment first. Two ids are
provided:erdifyregenerates the diagram (pre-commit fails the commit when
the file changed), anderdify-checknever writes and exits non-zero when the
committed diagram has drifted.--checkis part of the latter's entry point,
so overridingargscannot drop it. SQL DDL projects add
additional_dependencies: ['sqlglot>=25']rather than using a separate id. - The documentation site now renders a social card (
og:image) for every page,
so links shared on chat, social and link-preview surfaces show a real card
instead of a bare text entry. This enables mkdocs-material'ssocialplugin,
which pulls in themkdocs-material[imaging]dependencies and their system
libraries in the docs workflow. - The changelog is published as a page on the documentation site. It includes
the repository'sCHANGELOG.mdverbatim viapymdownx.snippets, so there is
still a single source of truth. - Every documentation page now has an edit link back to its source on GitHub
(content.action.edit;edit_uriwas already configured but Material never
rendered the button without the feature) and previous/next navigation in the
footer (navigation.footer).
Changed
-
The "No tables found" message now ends with a link to the troubleshooting
page, which did not exist when the message was written. -
The Datadog coverage upload is now also skipped for Dependabot. The existing
fork check covers pull requests from forks, but a Dependabot pull request's
head branch lives in this repository, and GitHub runs those with Dependabot
secrets rather than Actions secrets — so the step would have run with an
empty key and failed the requiredTests passedcheck on every dependency
bump. The condition matches on the actor: secrets cannot be referenced in an
if:conditional, and the documented job-level-env workaround would put the
API key in the environment of every step in the job. -
SECURITY.mdscopes its absolute claims to the core install. "Does not
execute / import / connect / send" holds for the stdlib-only core; the
erdify[sql]extra runs third-party code (sqlglot) in your process and is now
described as its own trust boundary. Added:--output/--injectdo write to
the paths you name, and the rendering step (PlantUML server, Mermaid, browser)
is outside erdify's control. The response times are stated as what a small
team aims for rather than a service-level guarantee. -
docs/usage/ci.mdleads with the--checkdrift gate and presents the
auto-commit workflow as the alternative, with its trade-off stated. The
workflow examples keep floating action tags for readability, and a note now
says so explicitly and tells readers to pin to a SHA in their own repository —
as erdify's own workflows do. -
Reduced decorative emoji in
SECURITY.mdandCONTRIBUTING.md, which people
reach when something is wrong or when they are trying to get set up. -
The "No tables found" warning is now actionable: it names the active
--includepatterns, reports how many.py/.sqlfiles were scanned and how
many matched, and distinguishes "nothing matched the patterns" (the usual
cause —--includedefaults tomodels.py, so models in e.g.schema.pyare
never seen) from "files matched but held no recognized models". -
The README now answers "why erdify and not X" right after the feature list,
with a condensed comparison table and a link to the full one. -
The README shows its example ERD as a live Mermaid diagram injected with
erdify --injectinstead of a committed PNG — the format the README itself
advertises as rendering natively on GitHub. Areadme-erdpre-commit hook
runs the same command with--check, so the embedded diagram cannot go stale
(and it dogfoods both flags on the project's own front page). -
The README badge row is down from ten to six: PyPI version, Python versions,
License, Tests, Coverage and a new docs badge. The Linting, Ruff, mypy and
download badges added rows without adding information a reader acts on. -
The PyPI project page now links to the documentation site
(https://erdify.devsuit.io/) instead of the README anchor on GitHub, and
gainsChangelogandIssueslinks. -
[tool.ruff] target-versionispy311, matchingrequires-python = ">=3.11"
instead of contradicting it withpy310. -
The documentation home page now leads with what erdify is, the
framework-comparison diagram and a three-line install-and-run, instead of
restating the sidebar. TheComparison,Python Parsing Limitationsand
Troubleshootingpages are in the nav. -
docs/frameworks/index.mdloads its second example image from the repository
instead ofraw.githubusercontent.com, matching the first one on the page. -
The Mermaid section of
docs/usage/output-formats.mdshows the.mmdsource
and the rendered diagram in side-by-side tabs; the rendered-only fence never
showed readers what the file actually contains. -
The required
Tests passedcheck now fails for a pull request from the
machine-writtenbadgesbranch intomain(the only base the test workflow
runs for). GitHub cannot bar a branch from being a pull-request source, and
such a pull request would otherwise look mergeable while replacing the README
onmainwith the branch's own. -
Test coverage is now uploaded to Datadog Code Coverage from the Linux /
Python 3.13 matrix leg, withcode-coverage.datadog.yamldefining the
service mapping and 90% total/patch PR gates (matching the existing
fail_under), andservice.datadog.yamlregistering erdify in the Datadog
Software Catalog. The upload is skipped on pull requests from forks, which
have no access to repository secrets; the workflow deliberately stays on the
pull_requesttrigger. -
The README now carries a coverage badge. Datadog exposes no public badge
endpoint, so pushes tomainpublish the percentage as a shields.io endpoint
payload on the orphanbadgesbranch of this repository, committed by
github-actions[bot]with the workflow's built-inGITHUB_TOKEN. Pull
requests never update it. Keeping the payload in the repository rather than in
a Gist or a third-party badge service means no personal credential is involved
and the badge survives any contributor leaving. -
CI now resolves
uvtolatest-knowninstead oflatest, so the version
installed in every workflow (including the PyPI publish job) is one whose
checksum ships with the pinnedsetup-uvrelease. Newuvversions reach CI
only through asetup-uvbump, which arrives as a reviewed, cooldown-gated
Dependabot PR. -
Dependabot's
github-actionsversion-update group now includesmajor, so
major action bumps arrive as a single grouped PR instead of one PR each. The
uventry deliberately keeps majors separate, and security updates are
unaffected in both.
Install: pip install erdify · Docs: https://erdify.devsuit.io/ · Full diff: v0.12.3...v0.13.0
v0.12.3
Maintenance patch. No runtime or user-facing change; the core install stays dependency-free.
Security
-
Updated two transitive development dependencies carrying open advisories, clearing all six Dependabot alerts (4 high, 2 moderate):
sqlparse0.5.5 → 0.6.0 — GHSA-prg7-hcfm-mfcr (ReDoS via dollar-quoted SQL literals), GHSA-pwgv-4x5q-6m9f, GHSA-f2ff-p2ww-7p4p, GHSA-3496-9g83-7v6xpymdown-extensions10.21.3 → 11.0.1 — GHSA-gm37-52c6-37mw, GHSA-9xwg-3r6f-jcx2
No previous release was affected.
erdifydeclares no runtime dependencies, and both packages are reached only through the development and documentation groups (sqlparseviadjango,pymdown-extensionsviamkdocs-material). This hardens the development and CI toolchain only.
Changed
- Dependabot now holds freshly published versions back for 7 days (
cooldown.default-days: 7on everyupdatesentry) before proposing a version update, giving the ecosystem and security researchers time to catch a compromised or broken release. Security updates are unaffected —cooldownapplies to version updates only. - Bumped CI actions to their latest majors:
astral-sh/setup-uv9.0.0 → 10.0.1,actions/configure-pages5.0.0 → 6.0.0,actions/upload-pages-artifact4.0.0 → 5.0.0, andactions/deploy-pages4.0.5 → 5.0.0. Repository infrastructure only.
Full Changelog: v0.12.2...v0.12.3
v0.12.2
Maintenance patch. No runtime or user-facing change; the core install stays dependency-free.
Changed
- Bumped development dependencies (
version-updatesgroup):sqlglot(30.15.0 → 30.17.0),ruff(0.16.2 → 0.16.3),mypy(2.3.0 → 2.3.1), andsqlalchemy(2.0.51 → 2.0.52). - The documentation site is now deployed through the GitHub Pages Actions workflow instead of pushing to the
gh-pagesbranch. Repository infrastructure only — the published site is unchanged.
Full Changelog: v0.12.1...v0.12.2
v0.12.1
Dev-deps-only patch. No runtime or user-facing change; the core install stays dependency-free.
Changed
- Bumped development dependencies:
ruff(0.16.0 → 0.16.2),sqlglot(30.14.0 → 30.15.0), anddjango(5.2.16 → 5.2.17).
Full Changelog: v0.12.0...v0.12.1
v0.12.0
Added
- SQL frontend:
UNIQUEsingle-column foreign keys now render as 1:1 (instead of N:1). Drawnchild ... parent:|o--||when the FK column isNOT NULL,|o--o|when nullable — the child end is|obecause aUNIQUEFK caps a parent at zero-or-one child. Both column-levelUNIQUEand single-column table-levelUNIQUE (col)(anonymous or namedCONSTRAINT ... UNIQUE (col)) are recognized; compositeUNIQUE (a, b)is out of scope. A unique non-primary-key column is also markedUKin the entity block, and--format jsongains auniqueboolean per field. Other frontends are unaffected (#97, #129).
Full changelog: v0.11.5...v0.12.0
v0.11.5
Maintenance patch release. Only development dependencies and build tooling
changed since v0.11.4; no runtime or user-facing change — the core install
stays dependency-free.
Changed
- Bumped development dependencies (
version-updatesgroup):sqlglot
(30.13.0 → 30.14.0) andruff(0.15.22 → 0.16.0); relaxed theuv-build
build requirement to>=0.11.19,<0.13.0. No runtime or user-facing change;
the core install stays dependency-free. - Pinned the ruff rule set (
[tool.ruff.lint] select = ["E", "F"]) so the
ruff 0.16.0 default-rule expansion (59 → 413 rules) stays behavior-neutral;
adopting the new rules is tracked separately.
Full changelog: v0.11.4...v0.11.5
v0.11.4
Fixed
- Structural link-table detection now covers composite-PK association tables with more than two foreign keys (ternary and higher-order joins), not just two-FK tables. A table whose primary key is made up entirely of foreign keys — with no payload columns — is flagged as a link table (
<< (L) link >>) regardless of its name or arity, and higher-order ones are drawn as a star of edges from each parent to the link entity. - The rule is now shared by every parser backend (Python AST, Core
Table(...)synthesis, and the SQL DDL frontend), so it can no longer drift between them (#118).
Full changelog: https://github.com/devsuit-berlin/erdify/blob/v0.11.4/CHANGELOG.md
v0.11.3
Dev-dependency-only patch release — no runtime or user-facing change. The core install stays dependency-free.
Changed
- Bumped development dependencies (
version-updatesgroup):ast-serialize,librt,mkdocs-material,mypy,ruff,sqlglot, anddjango(5.2.15 → 5.2.16).
Full changelog: https://github.com/devsuit-berlin/erdify/blob/main/CHANGELOG.md
Compare: v0.11.2...v0.11.3