nci-cidc-api-modules 1.2.54__py3-none-any.whl → 1.2.55__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. boot.py +8 -0
  2. cidc_api/__init__.py +1 -1
  3. cidc_api/config/db.py +0 -2
  4. cidc_api/models/dataset.py +80 -0
  5. cidc_api/models/db/stage1/additional_treatment_orm.py +8 -1
  6. cidc_api/models/db/stage1/adverse_event_orm.py +8 -1
  7. cidc_api/models/db/stage1/baseline_clinical_assessment_orm.py +8 -1
  8. cidc_api/models/db/stage1/comorbidity_orm.py +8 -1
  9. cidc_api/models/db/stage1/consent_group_orm.py +6 -6
  10. cidc_api/models/db/stage1/demographic_orm.py +8 -1
  11. cidc_api/models/db/stage1/disease_orm.py +8 -1
  12. cidc_api/models/db/stage1/exposure_orm.py +8 -1
  13. cidc_api/models/db/stage1/gvhd_diagnosis_acute_orm.py +8 -3
  14. cidc_api/models/db/stage1/gvhd_diagnosis_chronic_orm.py +8 -3
  15. cidc_api/models/db/stage1/gvhd_organ_acute_orm.py +8 -1
  16. cidc_api/models/db/stage1/gvhd_organ_chronic_orm.py +8 -1
  17. cidc_api/models/db/stage1/medical_history_orm.py +8 -1
  18. cidc_api/models/db/stage1/other_malignancy_orm.py +8 -1
  19. cidc_api/models/db/stage1/participant_orm.py +4 -5
  20. cidc_api/models/db/stage1/prior_treatment_orm.py +8 -2
  21. cidc_api/models/db/stage1/radiotherapy_dose_orm.py +8 -1
  22. cidc_api/models/db/stage1/response_by_system_orm.py +8 -1
  23. cidc_api/models/db/stage1/response_orm.py +9 -2
  24. cidc_api/models/db/stage1/specimen_orm.py +9 -25
  25. cidc_api/models/db/stage1/stem_cell_transplant_orm.py +8 -1
  26. cidc_api/models/db/stage1/surgery_orm.py +8 -1
  27. cidc_api/models/db/stage1/therapy_agent_dose_orm.py +8 -1
  28. cidc_api/models/db/stage1/treatment_orm.py +8 -1
  29. cidc_api/models/db/stage1/trial_orm.py +1 -2
  30. cidc_api/models/db/stage2/additional_treatment_orm.py +8 -1
  31. cidc_api/models/db/stage2/administrative_person_orm.py +8 -1
  32. cidc_api/models/db/stage2/administrative_role_assignment_orm.py +1 -0
  33. cidc_api/models/db/stage2/adverse_event_orm.py +8 -1
  34. cidc_api/models/db/stage2/arm_orm.py +5 -4
  35. cidc_api/models/db/stage2/baseline_clinical_assessment_orm.py +8 -1
  36. cidc_api/models/db/stage2/cohort_orm.py +5 -4
  37. cidc_api/models/db/stage2/comorbidity_orm.py +8 -1
  38. cidc_api/models/db/stage2/consent_group_orm.py +5 -5
  39. cidc_api/models/db/stage2/contact_orm.py +10 -1
  40. cidc_api/models/db/stage2/demographic_orm.py +8 -1
  41. cidc_api/models/db/stage2/disease_orm.py +8 -1
  42. cidc_api/models/db/stage2/exposure_orm.py +8 -1
  43. cidc_api/models/db/stage2/file_orm.py +4 -4
  44. cidc_api/models/db/stage2/gvhd_diagnosis_acute_orm.py +8 -3
  45. cidc_api/models/db/stage2/gvhd_diagnosis_chronic_orm.py +8 -3
  46. cidc_api/models/db/stage2/gvhd_organ_acute_orm.py +8 -1
  47. cidc_api/models/db/stage2/gvhd_organ_chronic_orm.py +8 -1
  48. cidc_api/models/db/stage2/institution_orm.py +4 -4
  49. cidc_api/models/db/stage2/medical_history_orm.py +8 -1
  50. cidc_api/models/db/stage2/other_clinical_endpoint_orm.py +9 -1
  51. cidc_api/models/db/stage2/other_malignancy_orm.py +8 -1
  52. cidc_api/models/db/stage2/participant_orm.py +6 -6
  53. cidc_api/models/db/stage2/prior_treatment_orm.py +9 -3
  54. cidc_api/models/db/stage2/publication_orm.py +5 -4
  55. cidc_api/models/db/stage2/radiotherapy_dose_orm.py +9 -2
  56. cidc_api/models/db/stage2/response_by_system_orm.py +8 -1
  57. cidc_api/models/db/stage2/response_orm.py +9 -2
  58. cidc_api/models/db/stage2/shipment_orm.py +5 -5
  59. cidc_api/models/db/stage2/shipment_specimen_orm.py +8 -2
  60. cidc_api/models/db/stage2/specimen_orm.py +9 -75
  61. cidc_api/models/db/stage2/stem_cell_transplant_orm.py +8 -1
  62. cidc_api/models/db/stage2/surgery_orm.py +8 -1
  63. cidc_api/models/db/stage2/therapy_agent_dose_orm.py +8 -1
  64. cidc_api/models/db/stage2/treatment_orm.py +8 -1
  65. cidc_api/models/db/stage2/trial_orm.py +1 -2
  66. cidc_api/models/pydantic/stage1/trial.py +1 -1
  67. cidc_api/models/pydantic/stage2/adverse_event.py +52 -25
  68. cidc_api/models/pydantic/stage2/comorbidity.py +15 -8
  69. cidc_api/models/pydantic/stage2/demographic.py +45 -28
  70. cidc_api/models/pydantic/stage2/disease.py +100 -58
  71. cidc_api/models/pydantic/stage2/exposure.py +14 -8
  72. cidc_api/models/pydantic/stage2/medical_history.py +15 -8
  73. cidc_api/models/pydantic/stage2/other_malignancy.py +17 -11
  74. cidc_api/models/pydantic/stage2/participant.py +27 -15
  75. cidc_api/models/pydantic/stage2/prior_treatment.py +2 -0
  76. cidc_api/models/pydantic/stage2/radiotherapy_dose.py +27 -14
  77. cidc_api/models/pydantic/stage2/response.py +42 -23
  78. cidc_api/models/pydantic/stage2/response_by_system.py +138 -30
  79. cidc_api/models/pydantic/stage2/specimen.py +2 -185
  80. cidc_api/models/pydantic/stage2/surgery.py +15 -7
  81. cidc_api/models/pydantic/stage2/therapy_agent_dose.py +27 -14
  82. cidc_api/models/pydantic/stage2/treatment.py +30 -16
  83. cidc_api/telemetry.py +13 -13
  84. {nci_cidc_api_modules-1.2.54.dist-info → nci_cidc_api_modules-1.2.55.dist-info}/METADATA +1 -1
  85. nci_cidc_api_modules-1.2.55.dist-info/RECORD +163 -0
  86. cidc_api/models/data.py +0 -28
  87. nci_cidc_api_modules-1.2.54.dist-info/RECORD +0 -163
  88. {nci_cidc_api_modules-1.2.54.dist-info → nci_cidc_api_modules-1.2.55.dist-info}/WHEEL +0 -0
  89. {nci_cidc_api_modules-1.2.54.dist-info → nci_cidc_api_modules-1.2.55.dist-info}/licenses/LICENSE +0 -0
  90. {nci_cidc_api_modules-1.2.54.dist-info → nci_cidc_api_modules-1.2.55.dist-info}/top_level.txt +0 -0
@@ -2,10 +2,11 @@ from __future__ import annotations
2
2
  from typing import List
3
3
 
4
4
  from pydantic import NonNegativeInt, PositiveFloat
5
- from sqlalchemy import ForeignKey
5
+ from sqlalchemy import ForeignKey, ForeignKeyConstraint
6
6
  from sqlalchemy.orm import Mapped, mapped_column, relationship
7
7
 
8
8
  from cidc_api.models.db.stage2.base_orm import BaseORM
9
+ from cidc_api.models.db.stage2.trial_orm import TrialORM
9
10
  from cidc_api.models.types import TobaccoSmokingStatus
10
11
 
11
12
 
@@ -13,6 +14,12 @@ class MedicalHistoryORM(BaseORM):
13
14
  __tablename__ = "medical_history"
14
15
  __repr_attrs__ = ["medical_history_id"]
15
16
  __data_category__ = "medical_history"
17
+ __table_args__ = (
18
+ ForeignKeyConstraint(["trial_id", "version"], [TrialORM.trial_id, TrialORM.version], ondelete="CASCADE"),
19
+ )
20
+
21
+ trial_id: Mapped[str]
22
+ version: Mapped[str]
16
23
 
17
24
  medical_history_id: Mapped[int] = mapped_column(primary_key=True)
18
25
  participant_id: Mapped[int] = mapped_column(ForeignKey("stage2.participant.participant_id", ondelete="CASCADE"))
@@ -1,14 +1,22 @@
1
1
  from __future__ import annotations
2
- from sqlalchemy import ForeignKey, String
2
+ from sqlalchemy import String, ForeignKey, ForeignKeyConstraint
3
3
  from sqlalchemy.orm import Mapped, mapped_column, relationship
4
4
 
5
5
  from cidc_api.models.db.stage2.base_orm import BaseORM
6
+ from cidc_api.models.db.stage2.trial_orm import TrialORM
6
7
  from cidc_api.models.types import YNU, ResponseSystem, ResponseSystemVersion
7
8
 
8
9
 
9
10
  class OtherClinicalEndpointORM(BaseORM):
10
11
  __tablename__ = "other_clinical_endpoint"
11
12
  __repr_attrs__ = ["other_clinical_endpoint_id", "name", "event"]
13
+ __data_category__ = "other_clinical_endpoint"
14
+ __table_args__ = (
15
+ ForeignKeyConstraint(["trial_id", "version"], [TrialORM.trial_id, TrialORM.version], ondelete="CASCADE"),
16
+ )
17
+
18
+ trial_id: Mapped[str]
19
+ version: Mapped[str]
12
20
 
13
21
  other_clinical_endpoint_id: Mapped[int] = mapped_column(primary_key=True)
14
22
  participant_id: Mapped[int] = mapped_column(ForeignKey("stage2.participant.participant_id", ondelete="CASCADE"))
@@ -1,9 +1,10 @@
1
1
  from __future__ import annotations
2
2
  from pydantic import NonPositiveInt
3
- from sqlalchemy import ForeignKey
3
+ from sqlalchemy import ForeignKey, ForeignKeyConstraint
4
4
  from sqlalchemy.orm import Mapped, mapped_column, relationship
5
5
 
6
6
  from cidc_api.models.db.stage2.base_orm import BaseORM
7
+ from cidc_api.models.db.stage2.trial_orm import TrialORM
7
8
  from cidc_api.models.types import UberonAnatomicalTerm, ICDO3MorphologicalCode, ICDO3MorphologicalTerm, MalignancyStatus
8
9
 
9
10
 
@@ -11,6 +12,12 @@ class OtherMalignancyORM(BaseORM):
11
12
  __tablename__ = "other_malignancy"
12
13
  __repr_attrs__ = ["other_malignancy_id", "primary_disease_site"]
13
14
  __data_category__ = "other_malignancy"
15
+ __table_args__ = (
16
+ ForeignKeyConstraint(["trial_id", "version"], [TrialORM.trial_id, TrialORM.version], ondelete="CASCADE"),
17
+ )
18
+
19
+ trial_id: Mapped[str]
20
+ version: Mapped[str]
14
21
 
15
22
  other_malignancy_id: Mapped[int] = mapped_column(primary_key=True)
16
23
  medical_history_id: Mapped[int] = mapped_column(
@@ -1,26 +1,26 @@
1
1
  from __future__ import annotations
2
2
  from typing import List
3
+
3
4
  from sqlalchemy import ForeignKey, ForeignKeyConstraint
4
5
  from sqlalchemy.orm import Mapped, mapped_column, relationship
5
6
 
6
7
  from cidc_api.models.db.stage2.base_orm import BaseORM
8
+ from cidc_api.models.db.stage2.trial_orm import TrialORM
7
9
  from cidc_api.models.types import OffStudyReason, YNU
8
10
 
9
11
 
10
12
  class ParticipantORM(BaseORM):
11
13
  __tablename__ = "participant"
12
- __repr_attrs__ = ["native_participant_id", "cimac_participant_id"]
14
+ __repr_attrs__ = ["participant_id", "native_participant_id", "cimac_participant_id"]
15
+ __data_category__ = "participant"
13
16
  __table_args__ = (
14
- ForeignKeyConstraint(
15
- ["trial_id", "version"], ["stage2.trial.trial_id", "stage2.trial.version"], ondelete="CASCADE"
16
- ),
17
+ ForeignKeyConstraint(["trial_id", "version"], [TrialORM.trial_id, TrialORM.version], ondelete="CASCADE"),
17
18
  )
18
- __data_category__ = "participant"
19
19
 
20
- participant_id: Mapped[int] = mapped_column(primary_key=True)
21
20
  trial_id: Mapped[str]
22
21
  version: Mapped[str]
23
22
 
23
+ participant_id: Mapped[int] = mapped_column(primary_key=True)
24
24
  native_participant_id: Mapped[str | None]
25
25
  cimac_participant_id: Mapped[str | None]
26
26
  consent_group_id: Mapped[int | None] = mapped_column(
@@ -2,11 +2,11 @@ from __future__ import annotations
2
2
  from typing import List
3
3
 
4
4
  from pydantic import NonPositiveInt, NegativeInt
5
- from sqlalchemy import ForeignKey
5
+ from sqlalchemy import ForeignKey, ForeignKeyConstraint
6
6
  from sqlalchemy.orm import Mapped, mapped_column, relationship
7
- from sqlalchemy.types import JSON
8
7
 
9
8
  from cidc_api.models.db.stage2.base_orm import BaseORM
9
+ from cidc_api.models.db.stage2.trial_orm import TrialORM
10
10
  from cidc_api.models.types import ConditioningRegimenType, StemCellDonorType
11
11
 
12
12
 
@@ -14,6 +14,12 @@ class PriorTreatmentORM(BaseORM):
14
14
  __tablename__ = "prior_treatment"
15
15
  __repr_attrs__ = ["prior_treatment_id", "type"]
16
16
  __data_category__ = "prior_treatment"
17
+ __table_args__ = (
18
+ ForeignKeyConstraint(["trial_id", "version"], [TrialORM.trial_id, TrialORM.version], ondelete="CASCADE"),
19
+ )
20
+
21
+ trial_id: Mapped[str]
22
+ version: Mapped[str]
17
23
 
18
24
  prior_treatment_id: Mapped[int] = mapped_column(primary_key=True)
19
25
  participant_id: Mapped[int] = mapped_column(ForeignKey("stage2.participant.participant_id", ondelete="CASCADE"))
@@ -24,6 +30,6 @@ class PriorTreatmentORM(BaseORM):
24
30
  prior_treatment_best_response: Mapped[str | None]
25
31
  prior_treatment_conditioning_regimen_type: Mapped[ConditioningRegimenType | None]
26
32
  prior_treatment_stem_cell_donor_type: Mapped[StemCellDonorType | None]
27
- prior_treatment_days_to_prior_transplant: Mapped[NegativeInt | None]
33
+ prior_treatment_days_from_transplant_to_treatment_initiation: Mapped[NegativeInt | None]
28
34
 
29
35
  participant: Mapped[ParticipantORM] = relationship(back_populates="prior_treatments", cascade="all, delete")
@@ -3,22 +3,23 @@ from sqlalchemy import ForeignKeyConstraint, ForeignKey
3
3
  from sqlalchemy.orm import Mapped, mapped_column, relationship
4
4
 
5
5
  from cidc_api.models.db.stage2.base_orm import BaseORM
6
+ from cidc_api.models.db.stage2.trial_orm import TrialORM
6
7
  from cidc_api.models.types import ConditioningRegimenType, StemCellDonorType
7
8
 
8
9
 
9
10
  class PublicationORM(BaseORM):
10
11
  __tablename__ = "publication"
11
12
  __repr_attrs__ = ["publication_id", "publication_title"]
13
+ __data_category__ = "publication"
12
14
  __table_args__ = (
13
- ForeignKeyConstraint(
14
- ["trial_id", "version"], ["stage2.trial.trial_id", "stage2.trial.version"], ondelete="CASCADE"
15
- ),
15
+ ForeignKeyConstraint(["trial_id", "version"], [TrialORM.trial_id, TrialORM.version], ondelete="CASCADE"),
16
16
  )
17
17
 
18
- publication_id: Mapped[int] = mapped_column(primary_key=True)
19
18
  trial_id: Mapped[str]
20
19
  version: Mapped[str]
21
20
 
21
+ publication_id: Mapped[int] = mapped_column(primary_key=True)
22
+
22
23
  digital_object_id: Mapped[str]
23
24
  pubmed_id: Mapped[str | None]
24
25
  publication_title: Mapped[str | None]
@@ -1,17 +1,18 @@
1
1
  from __future__ import annotations
2
2
  from pydantic import NonNegativeInt, NonNegativeFloat, PositiveFloat
3
3
 
4
- from sqlalchemy import ForeignKey
4
+ from sqlalchemy import ForeignKey, ForeignKeyConstraint
5
5
  from sqlalchemy.orm import Mapped, mapped_column, relationship
6
6
 
7
7
  from cidc_api.models.db.stage2.base_orm import BaseORM
8
+ from cidc_api.models.db.stage2.trial_orm import TrialORM
8
9
  from cidc_api.models.types import (
9
10
  RadiotherapyProcedure,
10
11
  UberonAnatomicalTerm,
11
12
  RadiotherapyDoseUnits,
13
+ RadiationExtent,
12
14
  YN,
13
15
  YNU,
14
- RadiationExtent,
15
16
  )
16
17
 
17
18
 
@@ -19,6 +20,12 @@ class RadiotherapyDoseORM(BaseORM):
19
20
  __tablename__ = "radiotherapy_dose"
20
21
  __repr_attrs__ = ["radiotherapy_dose_id", "procedure"]
21
22
  __data_category__ = "radiotherapy_dose"
23
+ __table_args__ = (
24
+ ForeignKeyConstraint(["trial_id", "version"], [TrialORM.trial_id, TrialORM.version], ondelete="CASCADE"),
25
+ )
26
+
27
+ trial_id: Mapped[str]
28
+ version: Mapped[str]
22
29
 
23
30
  radiotherapy_dose_id: Mapped[int] = mapped_column(primary_key=True)
24
31
  treatment_id: Mapped[int] = mapped_column(ForeignKey("stage2.treatment.treatment_id", ondelete="CASCADE"))
@@ -1,9 +1,10 @@
1
1
  from __future__ import annotations
2
2
  from pydantic import PositiveInt
3
- from sqlalchemy import ForeignKey, String
3
+ from sqlalchemy import String, ForeignKey, ForeignKeyConstraint
4
4
  from sqlalchemy.orm import Mapped, mapped_column, relationship
5
5
 
6
6
  from cidc_api.models.db.stage2.base_orm import BaseORM
7
+ from cidc_api.models.db.stage2.trial_orm import TrialORM
7
8
  from cidc_api.models.types import ResponseSystem, ResponseSystemVersion, BestOverallResponse, YNUNA, YN
8
9
 
9
10
 
@@ -11,6 +12,12 @@ class ResponseBySystemORM(BaseORM):
11
12
  __tablename__ = "response_by_system"
12
13
  __repr_attrs__ = ["response_by_system_id", "participant_id"]
13
14
  __data_category__ = "response_by_system"
15
+ __table_args__ = (
16
+ ForeignKeyConstraint(["trial_id", "version"], [TrialORM.trial_id, TrialORM.version], ondelete="CASCADE"),
17
+ )
18
+
19
+ trial_id: Mapped[str]
20
+ version: Mapped[str]
14
21
 
15
22
  response_by_system_id: Mapped[int] = mapped_column(primary_key=True)
16
23
  participant_id: Mapped[int] = mapped_column(ForeignKey("stage2.participant.participant_id", ondelete="CASCADE"))
@@ -1,17 +1,24 @@
1
1
  from __future__ import annotations
2
2
  from pydantic import NonNegativeInt
3
3
 
4
- from sqlalchemy import ForeignKey
4
+ from sqlalchemy import ForeignKey, ForeignKeyConstraint
5
5
  from sqlalchemy.orm import Mapped, mapped_column, relationship
6
6
 
7
7
  from cidc_api.models.db.stage2.base_orm import BaseORM
8
- from cidc_api.models.types import SurvivalStatus, YNUNA, YN, CauseOfDeath
8
+ from cidc_api.models.db.stage2.trial_orm import TrialORM
9
+ from cidc_api.models.types import SurvivalStatus, CauseOfDeath, YNUNA, YN
9
10
 
10
11
 
11
12
  class ResponseORM(BaseORM):
12
13
  __tablename__ = "response"
13
14
  __repr_attrs__ = ["response_id", "participant_id"]
14
15
  __data_category__ = "response"
16
+ __table_args__ = (
17
+ ForeignKeyConstraint(["trial_id", "version"], [TrialORM.trial_id, TrialORM.version], ondelete="CASCADE"),
18
+ )
19
+
20
+ trial_id: Mapped[str]
21
+ version: Mapped[str]
15
22
 
16
23
  response_id: Mapped[int] = mapped_column(primary_key=True)
17
24
  participant_id: Mapped[int] = mapped_column(ForeignKey("stage2.participant.participant_id", ondelete="CASCADE"))
@@ -6,6 +6,7 @@ from sqlalchemy import ForeignKey, ForeignKeyConstraint
6
6
  from sqlalchemy.orm import Mapped, mapped_column, relationship
7
7
 
8
8
  from cidc_api.models.db.stage2.base_orm import BaseORM
9
+ from cidc_api.models.db.stage2.trial_orm import TrialORM
9
10
  from cidc_api.models.types import AssayPriority, AssayType, Courier, ShipmentCondition, ShipmentQuality
10
11
 
11
12
 
@@ -13,16 +14,15 @@ class ShipmentORM(BaseORM):
13
14
  __tablename__ = "shipment"
14
15
  __repr_attrs__ = ["shipment_id", "institution_id", "trial_id"]
15
16
  __table_args__ = (
16
- ForeignKeyConstraint(
17
- ["trial_id", "version"], ["stage2.trial.trial_id", "stage2.trial.version"], ondelete="CASCADE"
18
- ),
17
+ ForeignKeyConstraint(["trial_id", "version"], [TrialORM.trial_id, TrialORM.version], ondelete="CASCADE"),
19
18
  )
20
19
 
21
- shipment_id: Mapped[int] = mapped_column(primary_key=True)
22
- institution_id: Mapped[int] = mapped_column(ForeignKey("stage2.institution.institution_id", ondelete="CASCADE"))
23
20
  trial_id: Mapped[str]
24
21
  version: Mapped[str]
25
22
 
23
+ shipment_id: Mapped[int] = mapped_column(primary_key=True)
24
+ institution_id: Mapped[int] = mapped_column(ForeignKey("stage2.institution.institution_id", ondelete="CASCADE"))
25
+
26
26
  manifest_id: Mapped[str]
27
27
  assay_priority: Mapped[AssayPriority | None]
28
28
  assay_type: Mapped[AssayType | None]
@@ -1,15 +1,21 @@
1
1
  from __future__ import annotations
2
- from datetime import datetime
3
2
 
4
- from sqlalchemy import ForeignKey
3
+ from sqlalchemy import ForeignKey, ForeignKeyConstraint
5
4
  from sqlalchemy.orm import Mapped, mapped_column, relationship
6
5
 
7
6
  from cidc_api.models.db.stage2.base_orm import BaseORM
7
+ from cidc_api.models.db.stage2.trial_orm import TrialORM
8
8
 
9
9
 
10
10
  class ShipmentSpecimenORM(BaseORM):
11
11
  __tablename__ = "shipment_specimen"
12
12
  __repr_attrs__ = ["specimen_id", "shipment_id"]
13
+ __table_args__ = (
14
+ ForeignKeyConstraint(["trial_id", "version"], [TrialORM.trial_id, TrialORM.version], ondelete="CASCADE"),
15
+ )
16
+
17
+ trial_id: Mapped[str]
18
+ version: Mapped[str]
13
19
 
14
20
  specimen_id: Mapped[int] = mapped_column(
15
21
  ForeignKey("stage2.specimen.specimen_id", ondelete="CASCADE"), primary_key=True
@@ -1,97 +1,31 @@
1
1
  from __future__ import annotations
2
- from datetime import datetime
3
- from typing import List
4
2
 
5
- from sqlalchemy import ForeignKey
3
+ from sqlalchemy import ForeignKey, ForeignKeyConstraint
6
4
  from sqlalchemy.orm import Mapped, mapped_column, relationship
7
5
 
8
6
  from cidc_api.models.db.stage2.base_orm import BaseORM
7
+ from cidc_api.models.db.stage2.trial_orm import TrialORM
9
8
  from cidc_api.models.types import (
10
9
  UberonAnatomicalTerm,
11
- ICDO3MorphologicalCode,
12
- SpecimenType,
13
- SpecimenDescription,
14
- TumorType,
15
- CollectionProcedure,
16
- FixationStabilizationType,
17
- PrimaryContainerType,
18
- VolumeUnits,
19
- ProcessedType,
20
- ConcentrationUnits,
21
- DerivativeType,
22
- PBMCRestingPeriodUsed,
23
- MaterialUnits,
24
- MaterialStorageCondition,
25
- QCCondition,
26
- ReplacementRequested,
27
- ResidualUse,
28
- DiagnosisVerification,
29
- AssayType,
30
10
  )
31
11
 
32
12
 
33
13
  class SpecimenORM(BaseORM):
34
14
  __tablename__ = "specimen"
35
15
  __repr_attrs__ = ["specimen_id", "participant_id", "cimac_id"]
16
+ __data_category__ = "specimen"
17
+ __table_args__ = (
18
+ ForeignKeyConstraint(["trial_id", "version"], [TrialORM.trial_id, TrialORM.version], ondelete="CASCADE"),
19
+ )
20
+
21
+ trial_id: Mapped[str]
22
+ version: Mapped[str]
36
23
 
37
24
  specimen_id: Mapped[int] = mapped_column(primary_key=True)
38
25
  participant_id: Mapped[int] = mapped_column(ForeignKey("stage2.participant.participant_id", ondelete="CASCADE"))
39
26
 
40
27
  cimac_id: Mapped[str]
41
- surgical_pathology_report_id: Mapped[str | None]
42
- clinical_report_id: Mapped[str | None]
43
- parent_specimen_id: Mapped[str | None]
44
- processed_specimen_id: Mapped[str | None]
45
- organ_site_of_collection: Mapped[UberonAnatomicalTerm | None]
46
- histology_behavior: Mapped[ICDO3MorphologicalCode | None]
47
- histology_behavior_description: Mapped[str | None]
48
28
  collection_event_name: Mapped[str]
49
- specimen_type: Mapped[SpecimenType | None]
50
- specimen_type_other: Mapped[str | None]
51
- specimen_description: Mapped[SpecimenDescription | None]
52
- tumor_type: Mapped[TumorType | None]
53
- collection_procedure: Mapped[CollectionProcedure | None]
54
- collection_procedure_other: Mapped[str | None]
55
- core_number: Mapped[str | None]
56
- fixation_stabilization_type: Mapped[FixationStabilizationType | None]
57
- primary_container_type: Mapped[PrimaryContainerType | None]
58
- primary_container_type_other: Mapped[str | None]
59
- volume: Mapped[float | None]
60
- volume_units: Mapped[VolumeUnits | None]
61
- processed_type: Mapped[ProcessedType | None]
62
- processed_volume: Mapped[float | None]
63
- processed_volume_units: Mapped[VolumeUnits | None]
64
- processed_concentration: Mapped[float | None]
65
- processed_concentration_units: Mapped[ConcentrationUnits | None]
66
- processed_quantity: Mapped[float | None]
67
- derivative_type: Mapped[DerivativeType | None]
68
- derivative_volume: Mapped[float | None]
69
- derivative_volume_units: Mapped[VolumeUnits | None]
70
- derivative_concentration: Mapped[float | None]
71
- derivative_concentration_units: Mapped[ConcentrationUnits | None]
72
- tumor_tissue_total_area_percentage: Mapped[float | None]
73
- viable_tumor_area_percentage: Mapped[float | None]
74
- viable_stroma_area_percentage: Mapped[float | None]
75
- necrosis_area_percentage: Mapped[float | None]
76
- fibrosis_area_percentage: Mapped[float | None]
77
- din: Mapped[float | None]
78
- a260_a280: Mapped[float | None]
79
- a260_a230: Mapped[float | None]
80
- pbmc_viability: Mapped[float | None]
81
- pbmc_recovery: Mapped[float | None]
82
- pbmc_resting_period_used: Mapped[PBMCRestingPeriodUsed | None]
83
- material_used: Mapped[float | None]
84
- material_used_units: Mapped[MaterialUnits | None]
85
- material_remaining: Mapped[float | None]
86
- material_remaining_units: Mapped[MaterialUnits | None]
87
- material_storage_condition: Mapped[MaterialStorageCondition | None]
88
- qc_condition: Mapped[QCCondition | None]
89
- replacement_requested: Mapped[ReplacementRequested | None]
90
- residual_use: Mapped[ResidualUse | None]
91
- comments: Mapped[str | None]
92
- diagnosis_verification: Mapped[DiagnosisVerification | None]
93
- intended_assay: Mapped[AssayType | None]
94
- date_ingested: Mapped[datetime | None]
95
29
  days_to_specimen_collection: Mapped[int]
96
30
  organ_site_of_collection: Mapped[UberonAnatomicalTerm]
97
31
 
@@ -1,10 +1,11 @@
1
1
  from __future__ import annotations
2
2
  from pydantic import NonNegativeInt
3
3
 
4
- from sqlalchemy import ForeignKey
4
+ from sqlalchemy import ForeignKey, ForeignKeyConstraint
5
5
  from sqlalchemy.orm import Mapped, mapped_column, relationship
6
6
 
7
7
  from cidc_api.models.db.stage2.base_orm import BaseORM
8
+ from cidc_api.models.db.stage2.trial_orm import TrialORM
8
9
  from cidc_api.models.types import StemCellDonorType, AllogeneicDonorType, StemCellSource, ConditioningRegimenType
9
10
 
10
11
 
@@ -12,6 +13,12 @@ class StemCellTransplantORM(BaseORM):
12
13
  __tablename__ = "stem_cell_transplant"
13
14
  __repr_attrs__ = ["stem_cell_transplant_id"]
14
15
  __data_category__ = "stem_cell_transplant"
16
+ __table_args__ = (
17
+ ForeignKeyConstraint(["trial_id", "version"], [TrialORM.trial_id, TrialORM.version], ondelete="CASCADE"),
18
+ )
19
+
20
+ trial_id: Mapped[str]
21
+ version: Mapped[str]
15
22
 
16
23
  stem_cell_transplant_id: Mapped[int] = mapped_column(primary_key=True)
17
24
  treatment_id: Mapped[int] = mapped_column(ForeignKey("stage2.treatment.treatment_id", ondelete="CASCADE"))
@@ -1,10 +1,11 @@
1
1
  from __future__ import annotations
2
2
  from pydantic import NonNegativeInt
3
3
 
4
- from sqlalchemy import ForeignKey
4
+ from sqlalchemy import ForeignKey, ForeignKeyConstraint
5
5
  from sqlalchemy.orm import Mapped, mapped_column, relationship
6
6
 
7
7
  from cidc_api.models.db.stage2.base_orm import BaseORM
8
+ from cidc_api.models.db.stage2.trial_orm import TrialORM
8
9
  from cidc_api.models.types import SurgicalProcedure, UberonAnatomicalTerm, YNU
9
10
 
10
11
 
@@ -12,6 +13,12 @@ class SurgeryORM(BaseORM):
12
13
  __tablename__ = "surgery"
13
14
  __repr_attrs__ = ["surgery_id", "procedure"]
14
15
  __data_category__ = "surgery"
16
+ __table_args__ = (
17
+ ForeignKeyConstraint(["trial_id", "version"], [TrialORM.trial_id, TrialORM.version], ondelete="CASCADE"),
18
+ )
19
+
20
+ trial_id: Mapped[str]
21
+ version: Mapped[str]
15
22
 
16
23
  surgery_id: Mapped[int] = mapped_column(primary_key=True)
17
24
  treatment_id: Mapped[int] = mapped_column(ForeignKey("stage2.treatment.treatment_id", ondelete="CASCADE"))
@@ -1,10 +1,11 @@
1
1
  from __future__ import annotations
2
2
  from pydantic import NonNegativeInt, NonNegativeFloat, PositiveFloat
3
3
 
4
- from sqlalchemy import ForeignKey
4
+ from sqlalchemy import ForeignKey, ForeignKeyConstraint
5
5
  from sqlalchemy.orm import Mapped, mapped_column, relationship
6
6
 
7
7
  from cidc_api.models.db.stage2.base_orm import BaseORM
8
+ from cidc_api.models.db.stage2.trial_orm import TrialORM
8
9
  from cidc_api.models.types import TherapyAgentDoseUnits, YNU
9
10
 
10
11
 
@@ -12,6 +13,12 @@ class TherapyAgentDoseORM(BaseORM):
12
13
  __tablename__ = "therapy_agent_dose"
13
14
  __repr_attrs__ = ["therapy_agent_dose_id", "therapy_agent_name"]
14
15
  __data_category__ = "therapy_agent_dose"
16
+ __table_args__ = (
17
+ ForeignKeyConstraint(["trial_id", "version"], [TrialORM.trial_id, TrialORM.version], ondelete="CASCADE"),
18
+ )
19
+
20
+ trial_id: Mapped[str]
21
+ version: Mapped[str]
15
22
 
16
23
  therapy_agent_dose_id: Mapped[int] = mapped_column(primary_key=True)
17
24
  treatment_id: Mapped[int] = mapped_column(ForeignKey("stage2.treatment.treatment_id", ondelete="CASCADE"))
@@ -1,10 +1,11 @@
1
1
  from __future__ import annotations
2
2
  from typing import List
3
3
 
4
- from sqlalchemy import ForeignKey
4
+ from sqlalchemy import ForeignKey, ForeignKeyConstraint
5
5
  from sqlalchemy.orm import Mapped, mapped_column, relationship
6
6
 
7
7
  from cidc_api.models.db.stage2.base_orm import BaseORM
8
+ from cidc_api.models.db.stage2.trial_orm import TrialORM
8
9
  from cidc_api.models.types import YNU, OffTreatmentReason
9
10
 
10
11
 
@@ -12,6 +13,12 @@ class TreatmentORM(BaseORM):
12
13
  __tablename__ = "treatment"
13
14
  __repr_attrs__ = ["treatment_id", "participant_id", "treatment_description"]
14
15
  __data_category__ = "treatment"
16
+ __table_args__ = (
17
+ ForeignKeyConstraint(["trial_id", "version"], [TrialORM.trial_id, TrialORM.version], ondelete="CASCADE"),
18
+ )
19
+
20
+ trial_id: Mapped[str]
21
+ version: Mapped[str]
15
22
 
16
23
  treatment_id: Mapped[int] = mapped_column(primary_key=True)
17
24
  participant_id: Mapped[int] = mapped_column(ForeignKey("stage2.participant.participant_id", ondelete="CASCADE"))
@@ -1,8 +1,7 @@
1
1
  from __future__ import annotations
2
- from datetime import datetime
3
2
  from typing import List
3
+ from datetime import datetime
4
4
 
5
- from sqlalchemy import ForeignKey
6
5
  from sqlalchemy.orm import Mapped, mapped_column, relationship
7
6
  from sqlalchemy.types import JSON
8
7
 
@@ -3,7 +3,7 @@ from pydantic import BeforeValidator
3
3
  from typing import List, Annotated
4
4
 
5
5
  from cidc_api.models.pydantic.base import Base
6
- from cidc_api.models.types import PrimaryPurposeType, AgeGroup
6
+ from cidc_api.models.types import TrialOrganization, TrialFundingAgency, AssayType, AgeGroup, PrimaryPurposeType
7
7
 
8
8
 
9
9
  class Trial(Base):
@@ -1,9 +1,9 @@
1
- from typing import Self
2
-
3
- from pydantic import NonNegativeInt, model_validator
1
+ from pydantic import NonNegativeInt
4
2
 
5
3
  from cidc_api.models.pydantic.base import Base
6
4
  from cidc_api.code_systems.ctcae import is_ctcae_other_term
5
+ from cidc_api.models.pydantic.base import forced_validator, forced_validators
6
+ from cidc_api.models.errors import ValueLocError
7
7
  from cidc_api.models.types import (
8
8
  CTCAEEventTerm,
9
9
  CTCAEEventCode,
@@ -13,11 +13,12 @@ from cidc_api.models.types import (
13
13
  SystemOrganClass,
14
14
  AttributionCause,
15
15
  AttributionLikelihood,
16
- YNU,
17
16
  YN,
17
+ YNU,
18
18
  )
19
19
 
20
20
 
21
+ @forced_validators
21
22
  class AdverseEvent(Base):
22
23
  __data_category__ = "adverse_event"
23
24
  __cardinality__ = "many"
@@ -76,26 +77,52 @@ class AdverseEvent(Base):
76
77
  # The individual therapy (therapy agent, radiotherapy, surgery, stem cell transplant) in the treatment that is attributed to the adverse event.
77
78
  individual_therapy: str | None = None
78
79
 
79
- @model_validator(mode="after")
80
- def validate_term_and_code_cr(self) -> Self:
81
- if not self.event_term and not self.event_code:
82
- raise ValueError("Please provide event_term or event_code or both")
83
- return self
84
-
85
- @model_validator(mode="after")
86
- def validate_event_other_specify_cr(self) -> Self:
87
- if (
88
- self.severity_grade_system == "CTCAE"
89
- and is_ctcae_other_term(self.event_term)
90
- and not self.event_other_specify
91
- ):
92
- raise ValueError(
93
- 'If severity_grade_system is "CTCAE" and the event_code or event_term are of type "Other, specify", please provide event_other_specify'
80
+ @forced_validator
81
+ @classmethod
82
+ def validate_term_and_code_cr(cls, data, info) -> None:
83
+ event_code = data.get("event_code", None)
84
+ event_term = data.get("event_term", None)
85
+
86
+ if not event_term and not event_code:
87
+ raise ValueLocError(
88
+ "Please provide event_term or event_code or both",
89
+ loc="event_term,event_code",
90
+ )
91
+
92
+ @forced_validator
93
+ @classmethod
94
+ def validate_event_other_specify_cr(cls, data, info) -> None:
95
+ event_other_specify = data.get("event_other_specify", None)
96
+ severity_grade_system = data.get("severity_grade_system", None)
97
+ event_term = data.get("event_term", None)
98
+
99
+ if severity_grade_system == "CTCAE" and is_ctcae_other_term(event_term) and not event_other_specify:
100
+ raise ValueLocError(
101
+ 'If severity_grade_system is "CTCAE" and the event_code or event_term are of type '
102
+ '"Other, specify", please provide event_other_specify',
103
+ loc="event_other_specify",
104
+ )
105
+
106
+ @forced_validator
107
+ @classmethod
108
+ def validate_system_organ_class_cr(cls, data, info) -> None:
109
+ event_other_specify = data.get("event_other_specify", None)
110
+ system_organ_class = data.get("system_organ_class", None)
111
+
112
+ if event_other_specify and not system_organ_class:
113
+ raise ValueLocError(
114
+ "If event_other_specify is provided, please provide system_organ_class.", loc="system_organ_class"
94
115
  )
95
- return self
96
116
 
97
- @model_validator(mode="after")
98
- def validate_system_organ_class_cr(self) -> Self:
99
- if self.event_other_specify and not self.system_organ_class:
100
- raise ValueError("If event_other_specify is provided, please provide system_organ_class.")
101
- return self
117
+ @forced_validator
118
+ @classmethod
119
+ def validate_days_to_resolution_of_event_chronology(cls, data, info) -> None:
120
+ days_to_onset_of_event = data.get("days_to_onset_of_event", None)
121
+ days_to_resolution_of_event = data.get("days_to_resolution_of_event", None)
122
+
123
+ if days_to_resolution_of_event is not None and days_to_onset_of_event is not None:
124
+ if int(days_to_resolution_of_event) < int(days_to_onset_of_event):
125
+ raise ValueLocError(
126
+ 'Violate "days_to_onset_of_event" <= "days_to_resolution_of_event"',
127
+ loc="days_to_resolution_of_event",
128
+ )