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

1from typing import Optional 

2 

3from sqlalchemy import Table, UniqueConstraint, Integer, ForeignKey, Column 

4from sqlalchemy.orm import Mapped, mapped_column, relationship 

5from sqlalchemy.dialects import mysql 

6 

7from .humans import Organisation 

8from .questionnaire import QuestionInstance 

9from .meta import Base 

10 

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) 

23 

24 

25class Tag(Base): 

26 __tablename__ = "tags" 

27 __table_args__ = ( 

28 UniqueConstraint("org_id", "name"), 

29 {"mysql_engine": "InnoDB", "mysql_charset": "utf8mb4"}, 

30 ) 

31 

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) 

39 

40 organisation: Mapped[Organisation] = relationship( 

41 Organisation, primaryjoin=org_id == Organisation.id, back_populates="tags" 

42 ) 

43 

44 question_instances = relationship( 

45 QuestionInstance, 

46 secondary=tags_qinstances_table, 

47 passive_deletes=True, 

48 lazy="dynamic", 

49 )