ERDiagram visualizes relational database architectures adhering strictly to Information Engineering (IE) / Crow's Foot notation—the industry standard for physical database schema modeling.
1. Overview & Crow's Foot Notation
Entity-Relationship Tables with Row-Anchored Crow's Foot NotationSource Code
Information Engineering (IE) Standard: Uses standard Crow's Foot vector markers (double vertical bar for exactly one, circle + crow's foot for zero or many, bar + crow's foot for one or many, and circle + bar for zero or one).
Column-Level Anchoring: Rather than connecting to arbitrary points on the table perimeter, Drawlib allows you to anchor lines directly to the specific primary key and foreign key table rows (start_column="id", end_column="user_id").
Key Badges: Automatically renders [PK] and [FK] tags next to column definitions with syntax highlighting.
SQL data type string (e.g. "INT", "VARCHAR(255)").
pk
bool
False
When True, displays the [PK] primary key badge.
fk
bool
False
When True, displays the [FK] foreign key badge.
nullable
bool
True
Whether the column allows NULL values.
fromdrawlib.diagrams.erimportColumnInfo# Single column & batch column registrationentity.add_column(name:str,type:str="",pk:bool=False,fk:bool=False,nullable:bool=True)->Entityentity.add_columns(columns:Sequence[Sequence[Any]|ColumnInfo],# Each item is a ColumnInfo or tuple (name, [type, pk, fk, nullable]))->Entity
Relationship (entity.connect & er.connect)
Parameter
Type
Default
Description
start / target
Entity
(Required)
Source and target Entity tables (entity.connect(target, ...) or er.connect(start, end, ...)).
Optional column name in start entity to anchor the wire directly to that row.
end_column
str | None
None
Optional column name in end entity to anchor the wire directly to that row.
label
str
""
Optional relationship text label along the connection line.
style
Style | None
None
Optional Style override for the relationship line and Crow's Foot markers.
text_style
Style | None
None
Optional Style override for the relationship label text.
routing
Literal["orthogonal", "direct"]
"orthogonal"
Line routing strategy ("orthogonal" Z-bends or "direct" straight line).
padding
float | tuple[float, float]
0.0
Gap distance between entity borders and line endpoints.
show
bool
True
Visibility flag for the relationship line.
Registration, Sizing & Rendering Methods
er.add(entity, xy=(cx, cy), show: bool | None = None) -> Entity: Places an entity table centered at (cx, cy) and returns the mutable Entity.
entity.connect(target, cardinality="1:*", ..., show=True) -> Relationship or er.connect(start, end, cardinality="1:*", ..., show=True) -> Relationship (and er.add_relationship(rel) -> Relationship): Connects two entities with Crow's Foot notation and returns a mutable Relationship (rel.show, rel.style, rel.text_style).
er.get_size() -> tuple[float, float]: Returns the overall (width, height) of the diagram.
er.draw(xy=(0.0, 0.0), *, scale: float = 1.0) -> None: Renders the ER diagram anchored at bottom-left xy, proportionally scaling table geometry, Crow's Foot markers, and font sizes by scale.
3. Supported Cardinality Notations
Cardinality String
Parent Marker
Child Marker
Standard Semantics
"1:*"
One (double vertical bar)
Zero or Many (circle + crow's foot)
One-to-Many (Default)
"1:1"
One (double vertical bar)
One (double vertical bar)
One-to-One
"1:1..*"
One (double vertical bar)
One or Many (bar + crow's foot)
Mandatory Child One-to-Many
"1:0..1"
One (double vertical bar)
Zero or One (circle + bar)
Optional Child One-to-One
"0..1:1"
Zero or One (circle + bar)
One (double vertical bar)
Optional Parent One-to-One
"0..1:*"
Zero or One (circle + bar)
Zero or Many (circle + crow's foot)
Optional Parent One-to-Many
"*:*"
Zero or Many (circle + crow's foot)
Zero or Many (circle + crow's foot)
Many-to-Many
fromdrawlib.canvasimportsave,setupfromdrawlib.diagrams.erimportERDiagram,Entityfromdrawlib.stylesimportColors,Stylesfromdrawlib.textimporttextsetup(width=128,height=96)er=ERDiagram(node_style=Styles.Neutral,edge_style=Styles.DarkBold,edge_text_style=Styles.Dark.patch(text_size=10.5),)# 7 supported Crow's Foot cardinality strings arranged in a clean 2-column catalogspecs=[# Left column (x_src=14, x_dst=49)('"1:*" (One-to-Many)',"1:*",14.0,49.0,80.0,"Parent","Child"),('"1:1" (One-to-One)',"1:1",14.0,49.0,57.0,"Parent","Child"),('"1:1..*" (Mandatory Child)',"1:1..*",14.0,49.0,34.0,"Parent","Child"),('"1:0..1" (Optional Child)',"1:0..1",14.0,49.0,11.0,"Parent","Child"),# Right column (x_src=79, x_dst=114)('"0..1:1" (Optional Parent 1:1)',"0..1:1",79.0,114.0,80.0,"Parent","Child"),('"0..1:*" (Optional Parent 1:N)',"0..1:*",79.0,114.0,57.0,"Parent","Child"),('"*:*" (Many-to-Many)',"*:*",79.0,114.0,34.0,"Left","Right"),]lbl_style=Styles.DarkBold.patch(text_size=10.5,text_color=Colors.Primary5)for_title_str,card,x1,x2,y,src_name,dst_nameinspecs:e_src=er.add(Entity(name=src_name,width=16.0,style=Styles.PrimaryNeutral),xy=(x1,y))e_dst=er.add(Entity(name=dst_name,width=16.0,style=Styles.Neutral),xy=(x2,y))e_src.connect(e_dst,cardinality=card,start_side="right",end_side="left")er.draw(xy=(0.0,0.0))fortitle_str,_card,x1,x2,y,_src_name,_dst_nameinspecs:text(((x1+x2)/2.0,y+6.5),title_str,style=lbl_style)save()
All Seven Crow's Foot Cardinality Notations in ERDiagram
4. E-Commerce Relational Schema with Column Anchors
The following four-table schema (users, orders, order_items, and products) anchors every relationship directly to its primary and foreign key rows:
Always Use Column Anchoring: Supplying start_column and end_column visually connects the specific foreign key attribute to its referenced primary key, making schemas intuitive and professional.
Width Budgeting: Tables with long data types (e.g., VARCHAR(255)) look best with a width of 28.0 to 34.0 canvas units.
Cardinality Strings: Always use explicit cardinality strings ("1:*", "1:1", etc.) rather than manual arrow heads.