Coverage for rfpy/model/graph.py: 96%
26 statements
« prev ^ index » next coverage.py v7.8.0, created at 2025-04-24 10:52 +0000
« prev ^ index » next coverage.py v7.8.0, created at 2025-04-24 10:52 +0000
1from typing import Optional
3from sqlalchemy import ForeignKey
4from sqlalchemy.orm import relationship, Mapped, mapped_column
5from sqlalchemy.dialects import mysql
6from sqlalchemy.sql.sqltypes import Integer
8from .humans import Organisation
9from .meta import Base
12class RelationshipType(Base):
13 __tablename__ = "relationship_types"
15 org_id: Mapped[Optional[str]] = mapped_column(
16 mysql.VARCHAR(length=50),
17 ForeignKey("organisations.id", onupdate="CASCADE", ondelete="CASCADE"),
18 nullable=True,
19 )
20 name: Mapped[Optional[str]] = mapped_column(mysql.VARCHAR(length=128), nullable=True)
21 description: Mapped[Optional[str]] = mapped_column(mysql.VARCHAR(length=256), nullable=True)
23 organisation = relationship(
24 Organisation,
25 primaryjoin=org_id == Organisation.id,
26 back_populates="relationship_types",
27 )
29 edges = relationship(
30 "Edge",
31 back_populates="relationship_type",
32 cascade="all, delete",
33 passive_deletes=True,
34 )
36 def __repr__(self) -> str:
37 return f'<RelationshipType - "{self.name}" #{self.id}>'
40class Edge(Base):
41 __tablename__ = "edges"
43 id = None # type: ignore
45 from_org_id: Mapped[str] = mapped_column(
46 mysql.VARCHAR(length=50),
47 ForeignKey("organisations.id", onupdate="CASCADE"),
48 primary_key=True,
49 nullable=False,
50 )
52 to_org_id: Mapped[str] = mapped_column(
53 mysql.VARCHAR(length=50),
54 ForeignKey("organisations.id", onupdate="CASCADE"),
55 primary_key=True,
56 nullable=False,
57 )
59 relationship_id: Mapped[int] = mapped_column(
60 Integer,
61 ForeignKey("relationship_types.id", ondelete="CASCADE"),
62 primary_key=True,
63 nullable=False,
64 )
66 relationship_type = relationship(
67 RelationshipType, back_populates="edges", uselist=False, lazy="joined"
68 )
70 from_org = relationship(
71 Organisation,
72 primaryjoin=from_org_id == Organisation.id,
73 back_populates="lower_edges",
74 lazy="joined",
75 )
77 to_org = relationship(
78 Organisation,
79 primaryjoin=to_org_id == Organisation.id,
80 back_populates="higher_edges",
81 lazy="joined",
82 )
84 @property
85 def relationship(self) -> str:
86 return self.relationship_type.name
88 def __repr__(self) -> str:
89 return f'<Edge - "{self.from_org_id}" to "{self.to_org_id}">'