nci-cidc-api-modules 1.2.54__py3-none-any.whl → 1.2.56__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/models/dataset.py +80 -0
  4. cidc_api/models/db/stage1/additional_treatment_orm.py +8 -1
  5. cidc_api/models/db/stage1/adverse_event_orm.py +8 -1
  6. cidc_api/models/db/stage1/baseline_clinical_assessment_orm.py +8 -1
  7. cidc_api/models/db/stage1/comorbidity_orm.py +8 -1
  8. cidc_api/models/db/stage1/consent_group_orm.py +6 -6
  9. cidc_api/models/db/stage1/demographic_orm.py +8 -1
  10. cidc_api/models/db/stage1/disease_orm.py +8 -1
  11. cidc_api/models/db/stage1/exposure_orm.py +8 -1
  12. cidc_api/models/db/stage1/gvhd_diagnosis_acute_orm.py +8 -3
  13. cidc_api/models/db/stage1/gvhd_diagnosis_chronic_orm.py +8 -3
  14. cidc_api/models/db/stage1/gvhd_organ_acute_orm.py +8 -1
  15. cidc_api/models/db/stage1/gvhd_organ_chronic_orm.py +8 -1
  16. cidc_api/models/db/stage1/medical_history_orm.py +8 -1
  17. cidc_api/models/db/stage1/other_malignancy_orm.py +8 -1
  18. cidc_api/models/db/stage1/participant_orm.py +4 -5
  19. cidc_api/models/db/stage1/prior_treatment_orm.py +8 -2
  20. cidc_api/models/db/stage1/radiotherapy_dose_orm.py +8 -1
  21. cidc_api/models/db/stage1/response_by_system_orm.py +8 -1
  22. cidc_api/models/db/stage1/response_orm.py +9 -2
  23. cidc_api/models/db/stage1/specimen_orm.py +9 -25
  24. cidc_api/models/db/stage1/stem_cell_transplant_orm.py +8 -1
  25. cidc_api/models/db/stage1/surgery_orm.py +8 -1
  26. cidc_api/models/db/stage1/therapy_agent_dose_orm.py +8 -1
  27. cidc_api/models/db/stage1/treatment_orm.py +8 -1
  28. cidc_api/models/db/stage1/trial_orm.py +1 -2
  29. cidc_api/models/db/stage2/additional_treatment_orm.py +8 -1
  30. cidc_api/models/db/stage2/administrative_person_orm.py +8 -1
  31. cidc_api/models/db/stage2/administrative_role_assignment_orm.py +1 -0
  32. cidc_api/models/db/stage2/adverse_event_orm.py +8 -1
  33. cidc_api/models/db/stage2/arm_orm.py +5 -4
  34. cidc_api/models/db/stage2/baseline_clinical_assessment_orm.py +8 -1
  35. cidc_api/models/db/stage2/cohort_orm.py +5 -4
  36. cidc_api/models/db/stage2/comorbidity_orm.py +8 -1
  37. cidc_api/models/db/stage2/consent_group_orm.py +5 -5
  38. cidc_api/models/db/stage2/contact_orm.py +10 -1
  39. cidc_api/models/db/stage2/demographic_orm.py +8 -1
  40. cidc_api/models/db/stage2/disease_orm.py +8 -1
  41. cidc_api/models/db/stage2/exposure_orm.py +8 -1
  42. cidc_api/models/db/stage2/file_orm.py +4 -4
  43. cidc_api/models/db/stage2/gvhd_diagnosis_acute_orm.py +8 -3
  44. cidc_api/models/db/stage2/gvhd_diagnosis_chronic_orm.py +8 -3
  45. cidc_api/models/db/stage2/gvhd_organ_acute_orm.py +8 -1
  46. cidc_api/models/db/stage2/gvhd_organ_chronic_orm.py +8 -1
  47. cidc_api/models/db/stage2/institution_orm.py +4 -4
  48. cidc_api/models/db/stage2/medical_history_orm.py +8 -1
  49. cidc_api/models/db/stage2/other_clinical_endpoint_orm.py +9 -1
  50. cidc_api/models/db/stage2/other_malignancy_orm.py +8 -1
  51. cidc_api/models/db/stage2/participant_orm.py +6 -6
  52. cidc_api/models/db/stage2/prior_treatment_orm.py +9 -3
  53. cidc_api/models/db/stage2/publication_orm.py +5 -4
  54. cidc_api/models/db/stage2/radiotherapy_dose_orm.py +9 -2
  55. cidc_api/models/db/stage2/response_by_system_orm.py +8 -1
  56. cidc_api/models/db/stage2/response_orm.py +9 -2
  57. cidc_api/models/db/stage2/shipment_orm.py +5 -5
  58. cidc_api/models/db/stage2/shipment_specimen_orm.py +8 -2
  59. cidc_api/models/db/stage2/specimen_orm.py +9 -75
  60. cidc_api/models/db/stage2/stem_cell_transplant_orm.py +8 -1
  61. cidc_api/models/db/stage2/surgery_orm.py +8 -1
  62. cidc_api/models/db/stage2/therapy_agent_dose_orm.py +8 -1
  63. cidc_api/models/db/stage2/treatment_orm.py +8 -1
  64. cidc_api/models/db/stage2/trial_orm.py +1 -2
  65. cidc_api/models/pydantic/stage1/response_by_system.py +62 -0
  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.56.dist-info}/METADATA +1 -1
  85. nci_cidc_api_modules-1.2.56.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.56.dist-info}/WHEEL +0 -0
  89. {nci_cidc_api_modules-1.2.54.dist-info → nci_cidc_api_modules-1.2.56.dist-info}/licenses/LICENSE +0 -0
  90. {nci_cidc_api_modules-1.2.54.dist-info → nci_cidc_api_modules-1.2.56.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
 
@@ -176,6 +176,19 @@ class ResponseBySystem(Base):
176
176
  loc="days_to_best_response",
177
177
  )
178
178
 
179
+ @forced_validator
180
+ @classmethod
181
+ def validate_progression_free_survival_disease_progression_chronology(cls, data, info) -> None:
182
+ progression = data.get("progression", None)
183
+ days_to_disease_progression = data.get("days_to_disease_progression", None)
184
+ progression_free_survival = data.get("progression_free_survival", None)
185
+
186
+ if progression == "Yes" and progression_free_survival != days_to_disease_progression:
187
+ raise ValueLocError(
188
+ 'Violate "progression_free_survival" = "days_to_disease_progression" when progression is PFS event',
189
+ loc="progression_free_survival",
190
+ )
191
+
179
192
  @model_validator(mode="after")
180
193
  def validate_days_to_last_vital_status_chronology(self) -> Self:
181
194
  if not self.response:
@@ -218,3 +231,52 @@ class ResponseBySystem(Base):
218
231
  loc="days_to_death,days_to_first_response,days_to_best_response,days_to_disease_progression",
219
232
  )
220
233
  return self
234
+
235
+ @model_validator(mode="after")
236
+ def validate_progression_free_survival_death_chronology(self) -> Self:
237
+ if not self.response:
238
+ return self
239
+
240
+ if (
241
+ self.progression_free_survival_event == "Yes"
242
+ and self.progression == "No"
243
+ and self.progression_free_survival != self.response.days_to_death
244
+ ):
245
+ raise ValueLocError(
246
+ 'Violate "progression_free_survival" = "days_to_death" when death is PFS event',
247
+ loc="progression_free_survival",
248
+ )
249
+ return self
250
+
251
+ @model_validator(mode="after")
252
+ def validate_progression_free_survival_event_no_or_unknown(self) -> Self:
253
+ if not self.response:
254
+ return self
255
+
256
+ pfs_event = self.progression_free_survival_event
257
+ if pfs_event in ["No", "Unknown"] and (self.days_to_disease_progression or self.response.days_to_death):
258
+ raise ValueLocError(
259
+ 'Violate "days_to_death" and "days_to_disease_progression" should be blank when PFS event is "No" or "Unknown"',
260
+ loc="progression_free_survival_event",
261
+ )
262
+ return self
263
+
264
+ @model_validator(mode="after")
265
+ def validate_progression_free_survival_event_consistent(self) -> Self:
266
+ if not self.response:
267
+ return self
268
+
269
+ progressed_or_dead = self.progression == "Yes" or self.response.survival_status == "Dead"
270
+ no_progression_and_alive = self.progression == "No" and self.response.survival_status == "Alive"
271
+ pfs_event = self.progression_free_survival_event
272
+ if (
273
+ (pfs_event == "Yes" and not progressed_or_dead)
274
+ or (progressed_or_dead and pfs_event != "Yes")
275
+ or (pfs_event == "No" and not no_progression_and_alive)
276
+ or (no_progression_and_alive and pfs_event != "No")
277
+ ):
278
+ raise ValueLocError(
279
+ 'Inconsistent flags for "progression_free_survival_event","progression" and "survival_status"',
280
+ loc="progression_free_survival_event",
281
+ )
282
+ return self
@@ -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):