One URL in. Schema docs out.
Database → db2md → Markdown → Mermaid ER
Connect with any SQLAlchemy URL. Discover databases. Introspect tables, FKs, indexes, and comments. Write one Markdown file per database with a Mermaid ER diagram — no hardcoded names, no config file.
pip install 'db2md[postgres]'
db2md --url 'postgresql+asyncpg://user:pass@localhost:5432/postgres'
# → ./schemas/<database>.md
Full documentation: edwinalkins.github.io/db2md
Why db2md?
| Async-native | SQLAlchemy 2.x + async drivers (asyncpg, aiomysql, aiosqlite) |
| Zero hardcoding | Everything comes from introspection |
| Docs you can commit | Markdown + Mermaid — preview on GitHub, MkDocs, Notion… |
| Library + CLI | Script it, or run db2md in CI |
Install
pip install 'db2md[postgres]' # or [mysql] / [sqlite] / [all]
# From this repo
uv sync --extra postgres
| Dialect | Extra | Driver |
|---|---|---|
| PostgreSQL | postgres |
asyncpg |
| MySQL / MariaDB | mysql |
aiomysql |
| SQLite | sqlite |
aiosqlite |
CLI
# List databases (skips system catalogs by default)
db2md --url 'postgresql+asyncpg://user:pass@localhost:5432/postgres' --list
# Document every non-system database → ./schemas/<db>.md
db2md --url 'postgresql+asyncpg://user:pass@localhost:5432/postgres'
# Specific databases / output path
db2md \
--url 'postgresql+asyncpg://user:pass@localhost:5432/postgres' \
-d myapp -d analytics \
-o ./docs/db
uv run db2md --url 'sqlite+aiosqlite:///./app.db' -o ./schemas
Options
| Flag | Description |
|---|---|
-u, --url |
SQLAlchemy URL (or set DATABASE_URL) |
-o, --output |
Output directory (default: schemas/), or a file when documenting a single -d |
-d, --database |
Database to document (repeatable). Default: all non-system DBs |
--schema |
Schema/namespace (default: dialect-specific — public for PostgreSQL) |
--list |
List databases and exit |
--include-system |
Include system databases |
-v, --verbose |
Debug logging |
--version |
Show version |
Bare dialects are upgraded to async drivers automatically (postgresql://… → postgresql+asyncpg://…, etc.).
Library API
import asyncio
from db2md import list_databases, generate_schema_markdown, export_schemas
URL = "postgresql+asyncpg://user:pass@localhost:5432/postgres"
async def main() -> None:
dbs = await list_databases(URL)
name, table_count, md = await generate_schema_markdown(URL, "myapp")
paths = await export_schemas(URL, "schemas")
print(dbs, name, table_count, paths)
asyncio.run(main())
Public symbols
| Symbol | Role |
|---|---|
list_databases(url, *, include_system=False) |
List database names (dialect-aware) |
generate_schema_markdown(url, database, *, schema=None) |
Returns (name, table_count, markdown) |
export_schemas(url, output="schemas", …) |
Write one .md file per database |
ColumnInfo / ForeignKeyInfo / IndexInfo / CheckConstraintInfo / TableInfo |
Introspection dataclasses |
Output
Each generated file contains:
- ER diagram — Mermaid
erDiagramwith PK/FK markers and inferred cardinalities (1–1, 1–N, N–N) - Tables — columns, nullability, defaults, primary keys, comments
- Foreign keys, unique constraints, check constraints (name + SQL), indexes (columns + UNIQUE)
Example sketch:
# Database schema — `myapp`
> Auto-generated on 2026-08-02 12:00:00 UTC (schema `public`, 2 table(s)).
## ER diagram
```mermaid
erDiagram
"users" {
INTEGER id "PK"
VARCHAR_255 email
}
"users" ||--|{ "notes" : "notes_user_id_fkey"
```
## Tables
### `users`
Application users
| Column | Type | Nullable | Default | PK | Comment |
|---|---|---|---|---|---|
| `id` | `INTEGER` | no | — | yes | Primary key |
…
Dialect behaviour
| Backend | Database discovery | Default schema |
|---|---|---|
| PostgreSQL | pg_database (non-template) |
public |
| MySQL / MariaDB | SHOW DATABASES |
current catalog |
| SQLite | single file DB | n/a |
| Other | current database only | dialect-dependent |
System databases skipped by default:
- PostgreSQL:
postgres,template0,template1 - MySQL / MariaDB:
mysql,information_schema,performance_schema,sys
Limitations
- Views, materialized views, and sequences are not documented yet (base tables only).
- Mermaid cardinalities are inferred from UNIQUE/PK constraints and FK nullability (junction tables → N–N). Details: docs/mermaid-cardinalities.md.
- Under SQLite,
-d/--databasedoes not switch files (one DB per path); a warning is logged.
Development
uv sync --all-extras --group dev
uv run ruff check src tests
uv run mypy src
uv run pytest
# Docs
uv sync --group docs
uv run mkdocs serve
See CONTRIBUTING.md.
License
MIT © edwinalkins
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file db2md-0.1.0.tar.gz.
File metadata
- Download URL: db2md-0.1.0.tar.gz
- Upload date:
- Size: 3.9 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.12.1 {"installer":{"name":"uv","version":"0.12.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
add5e615f37353987104afd9e31ba817bff670adb3ab9ed98c6ed18e3acc642a
|
|
| MD5 |
c12c4442e5cbc1ff1c8e8ad8c57178d2
|
|
| BLAKE2b-256 |
5cef18bfb544a63c518f5f240168de79153a0fe69d101beb416720250d2ae186
|
File details
Details for the file db2md-0.1.0-py3-none-any.whl.
File metadata
- Download URL: db2md-0.1.0-py3-none-any.whl
- Upload date:
- Size: 15.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.12.1 {"installer":{"name":"uv","version":"0.12.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ef54f3323239d4484d59516556f4ec6e1d45d002af6a4ddb04454c95ead38abc
|
|
| MD5 |
18d049d7ac53a79dd37d5f55d80d0d5f
|
|
| BLAKE2b-256 |
e1a1a49f7720b604bcbc99f826da3d6026e85a3ab0e9720d656a8cc8c87846d8
|