ERD

D3Blocks.erd(df, entities=None, steps: list = None, direction: str = None, show_columns: str = 'all', show_types: bool = True, nodesep: int = 50, ranksep: int = 90, font: dict = {'size': 12}, title: str = 'ERD - D3blocks', filepath: str = 'erd.html', figsize=[None, None], showfig: bool = True, overwrite: bool = True, notebook: bool = False, save_button: bool = True, show_side_panel: bool = True, show_top_panel: bool = True, dark_mode=True, color_background=None, return_html: bool = False, reset_properties: bool = True)

ERD block: entity-relationship diagrams of database schemas.

Entities are table boxes with one row per column (name, type and PK/FK/UK badges); relationships carry crow’s-foot cardinality markers and are dashed when non-identifying. Laid out with dagre. The input is a Mermaid erDiagram or a DataFrame of relationships.

Parameters:
  • df (pd.DataFrame, str or path-like) –

    • DataFrame with the relationships. Required columns: ‘source’, ‘target’. Optional columns: ‘source_card’ and ‘target_card’ (‘one’, ‘zero_or_one’, ‘one_or_more’ or ‘zero_or_more’; missing: no marker), ‘label’ and ‘identifying’ (bool; default True).

    • str: a Mermaid erDiagram, or Markdown text with a fenced mermaid block.

    • Path to a Markdown file (.md, .markdown) or a .mmd / .mermaid file. From Markdown, the first erDiagram block is used.

    Supported Mermaid: relationships ‘A ||–o{ B : label’ with all four markers per end, ‘–’ (identifying) and ‘..’ (non-identifying), entity blocks ‘A { type name PK “comment” }’ with PK/FK/UK and comma lists, a top-level ‘direction’ and ‘%%’ comments. Other statements raise a ValueError naming the line.

  • entities (pd.DataFrame or dict, (default: None)) –

    Per-entity attributes keyed by entity name (a ‘name’ column or the index):
    • ’label’: display text.

    • ’color’: header and border colour.

    • ’tooltip’: text shown on hover.

    • ’columns’: [{‘name’, ‘type’, ‘key’, ‘comment’}], where ‘key’ is ‘’, ‘PK’, ‘FK’, ‘UK’ or a comma list such as ‘PK,FK’.

    Entities that only occur in df are drawn without columns.

  • steps (list of dict, (default: None)) – Captioned walkthrough; “Walk through” in the top panel steps through it: [{‘title’: str, ‘caption’: str, ‘highlight’: {‘nodes’: […], ‘edges’: [(a, b), …]}}]. ‘nodes’ are entities, ‘edges’ are relationships (in either order). Each step highlights them, dims the rest and zooms to them. None: no walkthrough.

  • direction (str, (default: None)) – Layout direction: ‘LR’, ‘TB’ (or ‘TD’), ‘RL’ or ‘BT’. None: the Mermaid ‘direction’ statement if there is one, otherwise ‘LR’.

  • show_columns (str, (default: 'all')) –

    Columns shown in the table boxes; the top panel switches this at runtime.
    • ’all’: every column.

    • ’keys’: PK/FK/UK columns only.

    • ’none’: table names only.

  • show_types (bool, (default: True)) – Show the column types.

  • nodesep (int, (default: 50)) – Pixels between entities in the same rank.

  • ranksep (int, (default: 90)) – Pixels between ranks.

  • font (dict, (default: {'size': 12})) – Font properties.

  • title (str, (default: 'ERD - D3blocks')) – Title of the figure.

  • filepath (str, (default: 'erd.html')) – File path to save the output. None: return HTML only.

  • figsize (list, (default: [None, None])) – [width, height] in pixels. None: full window.

  • showfig (bool, (default: True)) – Open the chart in the browser.

  • overwrite (bool, (default: True)) – Overwrite an existing file.

  • notebook (bool, (default: False)) – Display inline in a Jupyter notebook, isolated in an iframe sized by figsize (default: full width x 650 px).

  • save_button (bool, (default: True)) – Show the SVG/PNG save buttons.

  • show_side_panel (bool, (default: True)) – Show the left side panels (Export / Save, Layout, Legend).

  • show_top_panel (bool, (default: True)) – Show the top bar (logo, search, columns, walk through, fit, theme).

  • dark_mode (bool or 'auto', (default: True)) –

    Initial theme; the theme button switches at runtime in every mode.
    • True: start in the dark theme.

    • False: start in the light theme.

    • ’auto’: follow the operating system theme until the theme button is used.

  • color_background (list of str, str, or None, (default: None)) – Backgrounds for center / top / side panels as [dark_hex, light_hex]. Named themes: 'streamlit', 'darkblue'. None → ['#222222', '#ffffff'].

  • return_html (bool, (default: False)) – Return the HTML string.

  • reset_properties (bool, (default: True)) – Recompute entity and relationship properties from the input.

Returns:

  • d3.node_properties (DataFrame of dictionary) – Entity properties; edit and call d3.show() to update.

  • d3.edge_properties (DataFrame) – Relationship properties; edit and call d3.show() to update.

  • d3.config (dictionary) – Configuration, including ‘steps’ and ‘show_columns’.

Examples

>>> from d3blocks import D3Blocks
>>> d3 = D3Blocks(frame=False)
>>> d3.erd('''
... erDiagram
...     customers ||--o{ orders : places
...     orders ||--|{ order_lines : contains
...     customers {
...         uuid id PK
...         text email UK
...     }
...     orders {
...         uuid id PK
...         uuid customer_id FK "who ordered"
...     }
... ''', show_columns='keys')

References

Input Data

The input is either a Mermaid erDiagram (string, Markdown or file) or a DataFrame of relationships with the columns source and target; all other columns are optional.

#       source       target source_card   target_card     label  identifying
# 0  customers       orders         one  zero_or_more    places         True
# 1     orders  order_lines         one   one_or_more  contains        False
  • Cardinalities: one, zero_or_one, one_or_more, zero_or_more; drawn as crow’s-foot markers. A missing cardinality draws no marker.

  • identifying=False draws a dashed line.

Per-entity attributes (label, color, tooltip, columns) are passed with entities. columns is a list of {'name', 'type', 'key', 'comment'} where key is '', 'PK', 'FK', 'UK' or a comma list such as 'PK,FK'.

Mermaid input

Supported: relationships with all four markers per end (||, |o/o|, }|/|{, }o/o{), -- (identifying) and .. (non-identifying) lines, entity blocks with type name PK "comment" rows, keys PK, FK, UK and comma lists, entities that are only used in relationships, a top-level direction (direction= wins over it) and %% comments. Other statements raise a ValueError naming the line (see Mermaid errors on the Flowgraph page).

from d3blocks import D3Blocks

d3 = D3Blocks(frame=False)
d3.erd('''
erDiagram
    strategy_definitions ||--o{ strategy_runs : "has runs"
    strategy_runs o|--o{ signals : contains
    signals o|--o{ orders : "may produce"
    orders ||--o{ order_fills : "has fills"
    strategy_definitions {
        uuid id PK
        text name
        bool enabled
    }
    signals {
        uuid id PK
        uuid run_id FK "nullable"
        text status
    }
''')

From Markdown, the first erDiagram block is used.

DataFrame input

import pandas as pd

df = pd.DataFrame({
    'source': ['customers', 'orders'],
    'target': ['orders', 'order_lines'],
    'source_card': ['one', 'one'],
    'target_card': ['zero_or_more', 'one_or_more'],
    'label': ['places', 'contains'],
})
entities = {
    'customers': {'columns': [{'name': 'id', 'type': 'uuid', 'key': 'PK'},
                              {'name': 'email', 'type': 'text', 'key': 'UK'}]},
    'orders': {'columns': [{'name': 'id', 'type': 'uuid', 'key': 'PK'},
                           {'name': 'customer_id', 'type': 'uuid', 'key': 'FK', 'comment': 'who ordered'}]},
}
d3.erd(df, entities=entities, direction='TB')

Large schemas

Tables without relationships, and separate groups of related tables, are laid out on their own and packed in rows, so the diagram keeps the window’s proportions. Columns in the top panel switches between all columns, keys only (PK/FK/UK, with a “+N more columns” row) and table names only, and re-runs the layout. show_columns='keys' starts there. Search finds tables and columns; a column hit pins its table and marks the row.

Walkthrough

Pass steps for a captioned walkthrough (▶ Walk through in the top panel). A step highlights entities (nodes) and relationships (edges, as (a, b) pairs in either order), dims the rest and zooms to them.

steps = [
    {'title': 'Customers place orders', 'caption': 'One customer has zero or more orders.',
     'highlight': {'nodes': ['customers', 'orders'], 'edges': [('customers', 'orders')]}},
    {'title': 'Order lines', 'caption': 'Every order has at least one line.',
     'highlight': {'edges': [('orders', 'order_lines')]}},
]
d3.erd(df, entities=entities, steps=steps)

Without steps there is no walkthrough. Keys: ← and → move, Space plays or pauses, Esc closes.

Theme

The theme button switches between dark and light at runtime; lines, crow’s-foot markers, table boxes, key badges and the caption bar follow the theme. dark_mode='auto' follows the operating system theme until the theme button is used. Exports keep the theme shown.

Interaction

  • Hover a table to highlight it, its relationships and its neighbours; click to pin.

  • Hover a relationship to see both cardinalities in words.

  • The Layout panel changes direction, columns, column types, spacing and font size.

  • The Legend panel lists the cardinalities, line styles and keys in use.

  • Export to SVG, PNG or JSON (including computed positions).

Jupyter and Streamlit

In a notebook, pass notebook=True. In Streamlit, generate the HTML with return_html=True and embed it with st.iframe; see streamlit/erd_streamlit_demo.py.