Coverage for rfpy/model/tags.py: 100%
16 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 Table, UniqueConstraint, Integer, ForeignKey, Column
4from sqlalchemy.orm import Mapped, mapped_column, relationship
5from sqlalchemy.dialects import mysql
7from .humans import Organisation
8from .questionnaire import QuestionInstance
9from .meta import Base
11tags_qinstances_table = Table(
12 "tags_qinstances",
13 Base.metadata,
14 Column("tag_id", Integer, ForeignKey("tags.id", ondelete="CASCADE"), index=True),
15 Column(
16 "question_instance_id",
17 Integer,
18 ForeignKey(QuestionInstance.id, ondelete="CASCADE"),
19 index=True,
20 ),
21 UniqueConstraint("tag_id", "question_instance_id"),
22)
25class Tag(Base):
26 __tablename__ = "tags"
27 __table_args__ = (
28 UniqueConstraint("org_id", "name"),
29 {"mysql_engine": "InnoDB", "mysql_charset": "utf8mb4"},
30 )
32 org_id: Mapped[Optional[str]] = mapped_column(
33 mysql.VARCHAR(length=50),
34 ForeignKey("organisations.id", ondelete="CASCADE", onupdate="CASCADE"),
35 nullable=True,
36 )
37 name: Mapped[str] = mapped_column(mysql.VARCHAR(length=128), nullable=False)
38 description: Mapped[Optional[str]] = mapped_column(mysql.VARCHAR(length=256), nullable=True)
40 organisation: Mapped[Organisation] = relationship(
41 Organisation, primaryjoin=org_id == Organisation.id, back_populates="tags"
42 )
44 question_instances = relationship(
45 QuestionInstance,
46 secondary=tags_qinstances_table,
47 passive_deletes=True,
48 lazy="dynamic",
49 )