Entity relationship diagrams for Python data model classes like Pydantic.
—
Erdantic provides a comprehensive command-line interface for generating entity relationship diagrams from fully qualified model or module names. The CLI supports various output formats, styling options, and configuration parameters.
# Primary command
erdantic [models_or_modules...] --out OUTPUT_FILE [options]
# Alternative module invocation
python -m erdantic [models_or_modules...] --out OUTPUT_FILE [options]# Main CLI function signature
def main(
models_or_modules: list[str],
out: Path,
terminal_models: list[str] = [],
termini: list[str] = [],
limit_search_models_to: list[str] = [],
dot: bool = False,
no_overwrite: bool = False,
quiet: int = 0,
verbose: int = 0,
list_plugins: Optional[bool] = False,
version: Optional[bool] = None,
):
"""Draw entity relationship diagrams (ERDs) for Python data model classes. Diagrams are
rendered using the Graphviz library. Currently supported data modeling frameworks are Pydantic,
attrs, and standard library dataclasses.
"""models_or_modules - One or more full dotted paths for data model classes, or modules containing data model classes to include in diagram (e.g., 'erdantic.examples.pydantic.Party')--out, -o - Output filename for the diagram (format inferred from extension)--terminal-model, -t - Full dotted paths for data model classes to set as terminal nodes. Can be repeated for multiple models--terminus - (Deprecated) Use --terminal-model instead--limit-search-models-to, -m - Plugin identifiers to limit model search to specific types. Can be repeated--dot, -d - Print DOT language representation to console instead of rendering image--no-overwrite - Prevent overwriting existing output files--quiet, -q - Decrease log verbosity (can be used multiple times)--verbose, -v - Increase log verbosity (can be used multiple times)--list-plugins - List active plugins and exit--version - Show erdantic version and exit# Generate diagram from specific model classes
erdantic my.models.User my.models.Post --out models.png
# Generate diagram from an entire module
erdantic my.models --out module_diagram.svg# Different output formats (inferred from extension)
erdantic my.models --out diagram.png # PNG image
erdantic my.models --out diagram.svg # SVG vector
erdantic my.models --out diagram.pdf # PDF document
erdantic my.models --out diagram.eps # EPS format# Generate DOT language representation instead of image
erdantic my.models --dot
# Save DOT to file for external processing
erdantic my.models --dot > models.dot# Stop analysis at specific models to control diagram complexity
erdantic my.models --terminal-model my.base.BaseEntity --out simplified.png
# Multiple terminal models
erdantic my.models \
--terminal-model my.base.BaseEntity \
--terminal-model my.shared.CommonMixin \
--out controlled.png# Limit to specific model types only
erdantic my.models --limit-search-models-to pydantic --out pydantic_only.png
# Multiple plugin types
erdantic my.models \
--limit-search-models-to pydantic \
--limit-search-models-to dataclasses \
--out filtered.png# Quiet operation (suppress most logging)
erdantic my.models --out quiet.png --quiet
# Very quiet (suppress almost all logging)
erdantic my.models --out very_quiet.png -qq
# Verbose logging (show debug information)
erdantic my.models --out debug.png --verbose
# Very verbose logging
erdantic my.models --out very_debug.png -vv# Prevent accidental overwriting
erdantic my.models --out existing.png --no-overwrite
# This will fail if existing.png already exists# Show version
erdantic --version
# List available plugins
erdantic --list-plugins# Analyze multiple modules with terminal models and filtering
erdantic \
my.user.models \
my.post.models \
my.comment.models \
--terminal-model my.base.TimestampedModel \
--terminal-model my.base.SoftDeleteModel \
--limit-search-models-to pydantic \
--out complex_project.svg \
--verbose#!/bin/bash
# Generate documentation diagrams for CI/CD
# Check if output is up to date
if [ "models.png" -ot "my/models.py" ]; then
echo "Regenerating model diagram..."
erdantic my.models --out models.png --no-overwrite || {
echo "Failed to generate diagram"
exit 1
}
fi# Generate diagrams for multiple modules
for module in user post comment admin; do
erdantic "my.${module}.models" --out "${module}_models.png"
done
# Generate both image and DOT versions
erdantic my.models --out models.svg
erdantic my.models --dot > models.dot# Module not found
erdantic nonexistent.module --out error.png
# Error: Unable to import 'nonexistent.module'
# Output directory doesn't exist
erdantic my.models --out /nonexistent/dir/diagram.png
# Error: Output directory does not exist
# File exists with --no-overwrite
erdantic my.models --out existing.png --no-overwrite
# Error: existing.png already exists, and you specified --no-overwrite
# Unsupported model type
erdantic my.unsupported.models --out error.png
# Error: Model type not supported, available plugins: [...]Many IDEs can be configured to run erdantic automatically:
// VS Code task example (.vscode/tasks.json)
{
"version": "2.0.0",
"tasks": [
{
"label": "Generate ERD",
"type": "shell",
"command": "erdantic",
"args": ["${workspaceFolder}/models", "--out", "docs/erd.png"],
"group": "build"
}
]
}def import_object_from_name(full_obj_name: str) -> Union[ModuleType, object]:
"""Import an object from a fully qualified name.
Args:
full_obj_name (str): Fully qualified name of object or module to import.
Returns:
Union[ModuleType, object]: The imported module or object.
Raises:
ModelOrModuleNotFoundError: If the module or object cannot be imported.
"""This utility function is used internally by the CLI to resolve the string arguments into actual Python objects, but can also be used programmatically for dynamic imports.
from erdantic.cli import import_object_from_name
# Import a module
my_module = import_object_from_name("my.models")
# Import a specific class
MyModel = import_object_from_name("my.models.MyModel")
# Import a function
my_function = import_object_from_name("my.utils.helper_function")Install with Tessl CLI
npx tessl i tessl/pypi-erdantic