Пример #1
0
class Site(Base):
    __tablename__ = 'site'
    siteId = Column('site_id', Integer, primary_key=True)
    siteName = Column('site_name', String(255), nullable=False)
    # The Google group for the site; this is a unique key used externally.
    googleGroup = Column('google_group',
                         String(255),
                         nullable=False,
                         unique=True)
    mayolinkClientNumber = Column('mayolink_client_number', Integer)
    organizationId = Column('organization_id', Integer,
                            ForeignKey('organization.organization_id'))
    # Deprecated; this is being replaced by organizationId.
    hpoId = Column('hpo_id', Integer, ForeignKey('hpo.hpo_id'))

    siteStatus = Column('site_status', Enum(SiteStatus))
    enrollingStatus = Column('enrolling_status', Enum(EnrollingStatus))
    launchDate = Column('launch_date', Date)
    notes = Column('notes', String(1024))
    latitude = Column('latitude', Float)
    longitude = Column('longitude', Float)
    timeZoneId = Column('time_zone_id', String(1024))
    directions = Column('directions', String(1024))
    physicalLocationName = Column('physical_location_name', String(1024))
    address1 = Column('address_1', String(1024))
    address2 = Column('address_2', String(1024))
    city = Column('city', String(255))
    state = Column('state', String(2))
    zipCode = Column('zip_code', String(10))
    phoneNumber = Column('phone_number', String(80))
    adminEmails = Column('admin_emails', String(4096))
    link = Column('link', String(255))
Пример #2
0
class ParticipantBase(object):
  """Mixin with shared columns for Participant and ParticipantHistory"""

  # Randomly assigned internal ID. We tack 'P' on the front whenever we use this externally.
  participantId = Column('participant_id', Integer, primary_key=True, autoincrement=False)
  # Assigned ID from PTSC. Recieved in request to create a new Participant.
  externalId = Column('external_id', BigInteger)

  # Incrementing version, starts at 1 and is incremented on each update.
  version = Column('version', Integer, nullable=False)

  # Randomly assigned ID used with Biobank. Prefixed with 'B' whenever we use this externally.
  biobankId = Column('biobank_id', Integer, nullable=False)

  lastModified = Column('last_modified', UTCDateTime6, nullable=False)
  signUpTime = Column('sign_up_time', UTCDateTime, nullable=False)

  # One or more HPO IDs in FHIR JSON. (The primary link is separately stored as hpoId.)
  providerLink = Column('provider_link', BLOB)

  # Both HealthPro and PTC can mutate participants; we use clientId to track
  # which system did it. An client ID of [email protected] means we created fake data for this
  # participant.
  clientId = Column('client_id', String(80))

  # Default values for withdrawal and suspension are managed through the DAO (instead of column
  # defaults here) to simplify insert v. update semantics.
  # Withdrawal is permanent, and indicates we should neither contact the participant nor use their
  # data in the future.
  withdrawalStatus = Column('withdrawal_status', Enum(WithdrawalStatus), nullable=False)

  # The time at which the participants set their withdrawal status to NO_USE.
  withdrawalTime = Column('withdrawal_time', UTCDateTime)
  withdrawalAuthored = Column('withdrawal_authored', UTCDateTime)
  withdrawalReason = Column('withdrawal_reason', Enum(WithdrawalReason))
  withdrawalReasonJustification = Column('withdrawal_reason_justification', UnicodeText)
  # Suspension may be temporary, and indicates we should not contact the participant but may
  # continue using their data.
  suspensionStatus = Column('suspension_status', Enum(SuspensionStatus), nullable=False)

  # The time at which the participant set their suspension status to NO_CONTACT.
  suspensionTime = Column('suspension_time', UTCDateTime)
  # If a participant is deemed to be a "ghost" i.e. not real or empty participant obj.
  isGhostId = Column('is_ghost_id', Boolean)
  # The date the participant was marked as ghost
  dateAddedGhost = Column('date_added_ghost', UTCDateTime)

  @declared_attr
  def hpoId(cls):
    return Column('hpo_id', Integer, ForeignKey('hpo.hpo_id'), nullable=False)

  @declared_attr
  def organizationId(cls):
    return Column('organization_id', Integer, ForeignKey('organization.organization_id'))

  @declared_attr
  def siteId(cls):
    return Column('site_id', Integer, ForeignKey('site.site_id'))
Пример #3
0
class HPO(Base):
  """An awardee, containing organizations (which in turn contain sites.)"""
  __tablename__ = 'hpo'
  hpoId = Column('hpo_id', Integer, primary_key=True, autoincrement=False)
  name = Column('name', String(20))
  displayName = Column('display_name', String(255))
  organizationType = Column('organization_type', Enum(OrganizationType),
                            default=OrganizationType.UNSET)
  organizations = relationship('Organization', cascade='all, delete-orphan',
                               order_by='Organization.externalId')
  isObsolete = Column('is_obsolete', Enum(ObsoleteStatus))

  __table_args__ = (
    UniqueConstraint('name'),
  )
Пример #4
0
class PatientStatus(Base):
    """
  Site patient status
  """
    __tablename__ = 'patient_status'

    # Primary Key
    id = Column('id',
                Integer,
                primary_key=True,
                autoincrement=True,
                nullable=False)
    # have mysql set the creation data for each new order
    created = Column('created', DateTime, nullable=True)
    # have mysql always update the modified data when the record is changed
    modified = Column('modified', DateTime, nullable=True)
    participantId = Column('participant_id',
                           Integer,
                           ForeignKey('participant.participant_id'),
                           nullable=False)
    patientStatus = Column('patient_status',
                           Enum(PatientStatusFlag),
                           nullable=False)
    hpoId = Column('hpo_id', Integer, ForeignKey('hpo.hpo_id'), nullable=False)
    organizationId = Column('organization_id',
                            Integer,
                            ForeignKey('organization.organization_id'),
                            nullable=False)
    comment = Column('comment', Text, nullable=True)

    __table_args__ = (UniqueConstraint('participant_id',
                                       'organization_id',
                                       name='uidx_patient_status'), )
Пример #5
0
class GenomicSetMember(Base):
    """
  Genomic Set Member model
  """
    __tablename__ = 'genomic_set_member'

    # Primary Key
    id = Column('id',
                Integer,
                primary_key=True,
                autoincrement=True,
                nullable=False)
    # have mysql set the creation data for each new order
    created = Column('created', DateTime, nullable=True)
    # have mysql always update the modified data when the record is changed
    modified = Column('modified', DateTime, nullable=True)

    genomicSetId = Column('genomic_set_id',
                          Integer,
                          ForeignKey('genomic_set.id'),
                          nullable=False)

    participantId = Column('participant_id',
                           Integer,
                           ForeignKey('participant.participant_id'),
                           nullable=False)
    nyFlag = Column('ny_flag', Integer, nullable=True)

    sexAtBirth = Column('sex_at_birth', String(20), nullable=True)
    genomeType = Column('genome_type', String(80), nullable=True)

    biobankOrderId = Column('biobank_order_id',
                            String(80),
                            ForeignKey('biobank_order.biobank_order_id'),
                            unique=False,
                            nullable=True)

    biobankId = Column('biobank_id', String(80), nullable=True)

    biobankOrderClientId = Column('biobank_order_client_Id',
                                  String(80),
                                  nullable=True)

    packageId = Column('package_id', String(250), nullable=True)

    validationStatus = Column('validation_status',
                              Enum(GenomicSetMemberStatus),
                              default=GenomicSetStatus.UNSET)
    validationFlags = Column('validation_flags',
                             MultiEnum(GenomicValidationFlag),
                             nullable=True)

    validatedTime = Column('validated_time', DateTime, nullable=True)

    sampleId = Column('sample_id', String(80), nullable=True)
    sampleType = Column('sample_type', String(50), nullable=True)
Пример #6
0
class HPO(Base):
  __tablename__ = 'hpo'
  hpoId = Column('hpo_id', Integer, primary_key=True, autoincrement=False)
  name = Column('name', String(20))
  displayName = Column('display_name', String(255))
  organizationType = Column('organization_type', Enum(OrganizationType),
                            default=OrganizationType.UNSET)
  __table_args__ = (
    UniqueConstraint('name'),
  )
class AggregateMetrics(MetricsBase):
    """Aggregate metric value within a metric set."""
    __tablename__ = 'aggregate_metrics'
    metricSetId = Column('metric_set_id',
                         String(50),
                         ForeignKey('metric_set.metric_set_id',
                                    ondelete='CASCADE'),
                         primary_key=True)
    metricsKey = Column('metrics_key', Enum(MetricsKey), primary_key=True)
    value = Column('value', String(50), primary_key=True)
    count = Column('count', Integer, nullable=False)
Пример #8
0
class Organization(Base):
  """An organization, under an awardee/HPO, and containing sites."""
  __tablename__ = 'organization'
  # Database ID for the organization
  organizationId = Column('organization_id', Integer, primary_key=True)
  # External ID for the organization, e.g. WISC_MADISON
  externalId = Column('external_id', String(80), nullable=False)
  # Human readable display name for the organization, e.g. University of Wisconsin, Madison
  displayName = Column('display_name', String(255), nullable=False)
  # Foreign key to awardee/hpo this organization belongs to.
  hpoId = Column('hpo_id', Integer, ForeignKey('hpo.hpo_id'), nullable=False)
  # Sites belonging to this organization.
  sites = relationship('Site', cascade='all, delete-orphan', order_by='Site.googleGroup')
  isObsolete = Column('is_obsolete', Enum(ObsoleteStatus))
class MetricSet(MetricsBase):
    """A version containing a set of metrics in the database, generated by a pipeline.

  Contains buckets with metrics grouped by HPO ID and date.
  """
    __tablename__ = 'metric_set'
    metricSetId = Column('metric_set_id', String(50), primary_key=True)
    metricSetType = Column('metric_set_type',
                           Enum(MetricSetType),
                           nullable=False)
    lastModified = Column('last_modified', UTCDateTime, nullable=False)
    metrics = relationship('AggregateMetrics',
                           cascade='all, delete-orphan',
                           passive_deletes=True)
Пример #10
0
class QuestionnaireBase(object):
    """Mixin containing columns for Questionnaire and QuestionnaireHistory"""
    questionnaireId = Column('questionnaire_id', Integer, primary_key=True)
    # Incrementing version, starts at 1 and is incremented on each update.
    version = Column('version', Integer, nullable=False)
    created = Column('created', UTCDateTime, nullable=False)
    lastModified = Column('last_modified', UTCDateTime, nullable=False)
    # The JSON representation of the questionnaire provided by the client.
    # Concepts and questions can be be parsed out of this for use in querying.
    resource = Column('resource', BLOB, nullable=False)
    status = Column('status',
                    Enum(QuestionnaireDefinitionStatus),
                    default=QuestionnaireDefinitionStatus.VALID)

    def asdict_with_children(self):
        return self.asdict(follow={'concepts': {}, 'questions': {}})
class PhysicalMeasurements(Base):
    __tablename__ = 'physical_measurements'
    physicalMeasurementsId = Column('physical_measurements_id',
                                    Integer,
                                    primary_key=True,
                                    autoincrement=False)
    participantId = Column('participant_id',
                           Integer,
                           ForeignKey('participant.participant_id'),
                           nullable=False)
    created = Column('created', UTCDateTime, nullable=False)
    resource = Column('resource', BLOB, nullable=False)
    final = Column('final', Boolean, nullable=False)
    # The ID that these measurements are an amendment of (points from new to old)
    amendedMeasurementsId = Column(
        'amended_measurements_id', Integer,
        ForeignKey('physical_measurements.physical_measurements_id'))
    logPositionId = Column('log_position_id',
                           Integer,
                           ForeignKey('log_position.log_position_id'),
                           nullable=False)
    # The site that created the physical measurements.
    createdSiteId = Column('created_site_id', Integer,
                           ForeignKey('site.site_id'))
    # The username / email of the HealthPro user that created the physical measurements.
    createdUsername = Column('created_username', String(255))
    # The site that finalized the physical measurements.
    finalizedSiteId = Column('finalized_site_id', Integer,
                             ForeignKey('site.site_id'))
    # The username / email of the HealthPro user that finalized the physical measurements.
    finalizedUsername = Column('finalized_username', String(255))
    logPosition = relationship('LogPosition')
    finalized = Column('finalized', UTCDateTime)
    #Restored/amended measurements will be UNSET.
    status = Column('status', Enum(PhysicalMeasurementsStatus))
    cancelledUsername = Column('cancelled_username', String(255))
    cancelledSiteId = Column('cancelled_site_id', Integer,
                             ForeignKey('site.site_id'))
    cancelledTime = Column('cancelled_time', UTCDateTime)
    reason = Column('reason', UnicodeText)
    measurements = relationship('Measurement', cascade='all, delete-orphan')
Пример #12
0
class GenomicSet(Base):
    """
  Genomic Set model
  """
    __tablename__ = 'genomic_set'

    genomicSetMember = relationship('GenomicSetMember',
                                    cascade='all, delete-orphan')

    # Primary Key
    id = Column('id',
                Integer,
                primary_key=True,
                autoincrement=True,
                nullable=False)
    # have mysql set the creation data for each new order
    created = Column('created', DateTime, nullable=True)
    # have mysql always update the modified data when the record is changed
    modified = Column('modified', DateTime, nullable=True)

    genomicSetName = Column('genomic_set_name', String(80), nullable=False)
    genomicSetCriteria = Column('genomic_set_criteria',
                                String(80),
                                nullable=False)
    genomicSetVersion = Column('genomic_set_version', Integer, nullable=False)
    # genomic set file
    genomicSetFile = Column('genomic_set_file', String(250), nullable=True)
    # genomic set file timestamp
    genomicSetFileTime = Column('genomic_set_file_time',
                                DateTime,
                                nullable=True)

    genomicSetStatus = Column('genomic_set_status',
                              Enum(GenomicSetStatus),
                              default=GenomicSetStatus.UNSET)
    validatedTime = Column('validated_time', DateTime, nullable=True)

    __table_args__ = (UniqueConstraint('genomic_set_name',
                                       'genomic_set_version',
                                       name='uidx_genomic_name_version'), )
Пример #13
0
class _CodeBase(object):
    """Mixin with shared columns for Code and CodeHistory"""
    codeId = Column('code_id', Integer, primary_key=True)
    system = Column('system', String(255), nullable=False)
    value = Column('value', String(80), nullable=False)
    # OMOP codes are supposed to be at most 50 characters long; for legacy codes that exceeded this
    # limit, we populate a shortened version for use in OMOP here. Otherwise, shortValue is identical
    # to value.
    shortValue = Column('short_value', String(50))
    display = Column('display', UnicodeText)
    topic = Column('topic', UnicodeText)
    codeType = Column('code_type', Enum(CodeType), nullable=False)
    mapped = Column('mapped', Boolean, nullable=False)
    created = Column('created', UTCDateTime, nullable=False)

    @declared_attr
    def codeBookId(cls):
        return Column('code_book_id', Integer,
                      ForeignKey('code_book.code_book_id'))

    @declared_attr
    def parentId(cls):
        return Column('parent_id', Integer, ForeignKey('code.code_id'))
class ParticipantSummary(Base):
    """Summary fields extracted from participant data (combined from multiple tables).
  Consented participants only."""
    __tablename__ = 'participant_summary'
    participantId = Column('participant_id',
                           Integer,
                           ForeignKey('participant.participant_id'),
                           primary_key=True,
                           autoincrement=False)
    biobankId = Column('biobank_id', Integer, nullable=False)
    # PTC string fields will generally be limited to 255 chars; set our field lengths accordingly to
    # ensure that long values can be inserted.
    firstName = Column('first_name', String(255), nullable=False)
    middleName = Column('middle_name', String(255))
    lastName = Column('last_name', String(255), nullable=False)
    zipCode = Column('zip_code', String(10))
    stateId = Column('state_id', Integer, ForeignKey('code.code_id'))
    city = Column('city', String(255))
    streetAddress = Column('street_address', String(255))
    phoneNumber = Column('phone_number', String(80))
    email = Column('email', String(255), nullable=False)
    recontactMethodId = Column('recontact_method_id', Integer,
                               ForeignKey('code.code_id'))
    languageId = Column('language_id', Integer, ForeignKey('code.code_id'))
    dateOfBirth = Column('date_of_birth', Date)
    genderIdentityId = Column('gender_identity_id', Integer,
                              ForeignKey('code.code_id'))
    sexId = Column('sex_id', Integer, ForeignKey('code.code_id'))
    sexualOrientationId = Column('sexual_orientation_id', Integer,
                                 ForeignKey('code.code_id'))
    educationId = Column('education_id', Integer, ForeignKey('code.code_id'))
    incomeId = Column('income_id', Integer, ForeignKey('code.code_id'))
    enrollmentStatus = Column('enrollment_status',
                              Enum(EnrollmentStatus),
                              default=EnrollmentStatus.INTERESTED)
    race = Column('race', Enum(Race), default=Race.UNSET)
    physicalMeasurementsStatus = Column(
        'physical_measurements_status',
        Enum(PhysicalMeasurementsStatus),
        default=PhysicalMeasurementsStatus.UNSET)
    # The first time that physical measurements were submitted for the participant.
    physicalMeasurementsTime = Column('physical_measurements_time',
                                      UTCDateTime)
    signUpTime = Column('sign_up_time', UTCDateTime)
    hpoId = Column('hpo_id', Integer, ForeignKey('hpo.hpo_id'), nullable=False)

    # Fields for which questionnaires have been submitted, and at what times.
    consentForStudyEnrollment = Column('consent_for_study_enrollment',
                                       Enum(QuestionnaireStatus),
                                       default=QuestionnaireStatus.UNSET)
    consentForStudyEnrollmentTime = Column('consent_for_study_enrollment_time',
                                           UTCDateTime)
    consentForElectronicHealthRecords = Column(
        'consent_for_electronic_health_records',
        Enum(QuestionnaireStatus),
        default=QuestionnaireStatus.UNSET)
    consentForElectronicHealthRecordsTime = Column(
        'consent_for_electronic_health_records_time', UTCDateTime)
    consentForCABoR = Column('consent_for_cabor',
                             Enum(QuestionnaireStatus),
                             default=QuestionnaireStatus.UNSET)
    consentForCABoRTime = Column('consent_for_cabor_time', UTCDateTime)
    questionnaireOnOverallHealth = Column('questionnaire_on_overall_health',
                                          Enum(QuestionnaireStatus),
                                          default=QuestionnaireStatus.UNSET)
    questionnaireOnOverallHealthTime = Column(
        'questionnaire_on_overall_health_time', UTCDateTime)
    questionnaireOnLifestyle = Column('questionnaire_on_lifestyle',
                                      Enum(QuestionnaireStatus),
                                      default=QuestionnaireStatus.UNSET)
    questionnaireOnLifestyleTime = Column('questionnaire_on_lifestyle_time',
                                          UTCDateTime)
    questionnaireOnTheBasics = Column('questionnaire_on_the_basics',
                                      Enum(QuestionnaireStatus),
                                      default=QuestionnaireStatus.UNSET)
    questionnaireOnTheBasicsTime = Column('questionnaire_on_the_basics_time',
                                          UTCDateTime)
    questionnaireOnHealthcareAccess = Column(
        'questionnaire_on_healthcare_access',
        Enum(QuestionnaireStatus),
        default=QuestionnaireStatus.UNSET)
    questionnaireOnHealthcareAccessTime = Column(
        'questionnaire_on_healthcare_access_time', UTCDateTime)
    questionnaireOnMedicalHistory = Column('questionnaire_on_medical_history',
                                           Enum(QuestionnaireStatus),
                                           default=QuestionnaireStatus.UNSET)
    questionnaireOnMedicalHistoryTime = Column(
        'questionnaire_on_medical_history_time', UTCDateTime)
    questionnaireOnMedications = Column('questionnaire_on_medications',
                                        Enum(QuestionnaireStatus),
                                        default=QuestionnaireStatus.UNSET)
    questionnaireOnMedicationsTime = Column(
        'questionnaire_on_medications_time', UTCDateTime)
    questionnaireOnFamilyHealth = Column('questionnaire_on_family_health',
                                         Enum(QuestionnaireStatus),
                                         default=QuestionnaireStatus.UNSET)
    questionnaireOnFamilyHealthTime = Column(
        'questionnaire_on_family_health_time', UTCDateTime)

    # Fields for which samples have been received, and at what times.
    sampleStatus1SST8 = Column('sample_status_1sst8',
                               Enum(SampleStatus),
                               default=SampleStatus.UNSET)
    sampleStatus1SST8Time = Column('sample_status_1sst8_time', UTCDateTime)
    sampleStatus1PST8 = Column('sample_status_1pst8',
                               Enum(SampleStatus),
                               default=SampleStatus.UNSET)
    sampleStatus1PST8Time = Column('sample_status_1pst8_time', UTCDateTime)
    sampleStatus1HEP4 = Column('sample_status_1hep4',
                               Enum(SampleStatus),
                               default=SampleStatus.UNSET)
    sampleStatus1HEP4Time = Column('sample_status_1hep4_time', UTCDateTime)
    sampleStatus1ED04 = Column('sample_status_1ed04',
                               Enum(SampleStatus),
                               default=SampleStatus.UNSET)
    sampleStatus1ED04Time = Column('sample_status_1ed04_time', UTCDateTime)
    sampleStatus1ED10 = Column('sample_status_1ed10',
                               Enum(SampleStatus),
                               default=SampleStatus.UNSET)
    sampleStatus1ED10Time = Column('sample_status_1ed10_time', UTCDateTime)
    sampleStatus2ED10 = Column('sample_status_2ed10',
                               Enum(SampleStatus),
                               default=SampleStatus.UNSET)
    sampleStatus2ED10Time = Column('sample_status_2ed10_time', UTCDateTime)
    sampleStatus1UR10 = Column('sample_status_1ur10',
                               Enum(SampleStatus),
                               default=SampleStatus.UNSET)
    sampleStatus1UR10Time = Column('sample_status_1ur10_time', UTCDateTime)
    sampleStatus1SAL = Column('sample_status_1sal',
                              Enum(SampleStatus),
                              default=SampleStatus.UNSET)
    sampleStatus1SALTime = Column('sample_status_1sal_time', UTCDateTime)

    numCompletedBaselinePPIModules = Column(
        'num_completed_baseline_ppi_modules', SmallInteger, default=0)
    numCompletedPPIModules = Column('num_completed_ppi_modules',
                                    SmallInteger,
                                    default=0)

    # The number of BiobankStoredSamples recorded for this participant, limited to those samples
    # where testCode is one of the baseline tests (listed in the config).
    numBaselineSamplesArrived = Column('num_baseline_samples_arrived',
                                       SmallInteger,
                                       default=0)
    samplesToIsolateDNA = Column('samples_to_isolate_dna',
                                 Enum(SampleStatus),
                                 default=SampleStatus.UNSET)

    # Withdrawal from the study of the participant's own accord.
    withdrawalStatus = Column('withdrawal_status',
                              Enum(WithdrawalStatus),
                              nullable=False,
                              onupdate=WithdrawalStatus.NOT_WITHDRAWN)
    withdrawalTime = Column('withdrawal_time', UTCDateTime)

    suspensionStatus = Column('suspension_status',
                              Enum(SuspensionStatus),
                              nullable=False,
                              onupdate=SuspensionStatus.NOT_SUSPENDED)
    suspensionTime = Column('suspension_time', UTCDateTime)

    participant = relationship("Participant",
                               back_populates="participantSummary")
Пример #15
0
class BiobankOrderBase(object):
  """An order requesting samples.

  The order contains a list of samples stored in BiobankOrderedSample; the actual delivered and
  stored samples are tracked in BiobankStoredSample. Our reconciliation report compares the two.
  """
  _MAIN_ID_SYSTEM = 'https://orders.mayomedicallaboratories.com'

  # A GUID for the order, provided by Biobank. This is the ID assigned in HealthPro, which is sent
  # to us as an identifier with the mayomedicallaboritories.com "system".
  biobankOrderId = Column('biobank_order_id', String(80), primary_key=True)

  # Incrementing version, starts at 1 and is incremented on each update.
  version = Column('version', Integer, nullable=False)

  # The username / email of the HealthPro user that created the order -- createdInfo['author']
  # in the resulting JSON.
  sourceUsername = Column('source_username', String(255))

  # The username / email of the HealthPro user that collected the order -- collectedInfo['author']
  # in the resulting JSON.
  collectedUsername = Column('collected_username', String(255))

  # The username / email of the HealthPro user that processed the order -- processedInfo['author']
  # in the resulting JSON.
  processedUsername = Column('processed_username', String(255))

  # The username / email of the HealthPro user that finalized the order -- finalizedInfo['author']
  # in the resulting JSON.
  finalizedUsername = Column('finalized_username', String(255))
  finalizedTime = Column('finalized_time', UTCDateTime)

  # cancelled finalized order may still be shipped to biobank for destruction
  # orderstatus can be cancelled/amended/restored
  # A null value or UNSET == finalized (i.e. the current accepted value)

  orderStatus = Column('order_status', Enum(BiobankOrderStatus))
  # a cancelled or edited order must have a reason. Set on the old row because cancelled orders
  # don't create a new row like amended orders do.
  amendedReason = Column('amended_reason', UnicodeText)
  lastModified = Column('last_modified', UTCDateTime)

  restoredUsername = Column('restored_username', String(255))
  restoredTime = Column('restored_time', UTCDateTime)

  amendedUsername = Column('amended_username', String(255))
  amendedTime = Column('amended_time', UTCDateTime)

  cancelledUsername = Column('cancelled_username', String(255))
  cancelledTime = Column('cancelled_time', UTCDateTime)

  # Additional fields stored for future use.
  created = Column('created', UTCDateTime, nullable=False)
  collectedNote = Column('collected_note', UnicodeText)
  processedNote = Column('processed_note', UnicodeText)
  finalizedNote = Column('finalized_note', UnicodeText)

  @declared_attr
  def participantId(cls):
    return Column('participant_id', Integer, ForeignKey(
      'participant.participant_id'), nullable=False)

  @declared_attr
  def amendedBiobankOrderId(cls):
    return Column('amended_biobank_order_id', String(80),
                  ForeignKey('biobank_order.biobank_order_id'))

  # For syncing new orders.
  @declared_attr
  def logPositionId(cls):
    return Column('log_position_id', Integer, ForeignKey(
      'log_position.log_position_id'), nullable=False)


  # The site that created the order -- createdInfo['site'] in the resulting JSON
  @declared_attr
  def sourceSiteId(cls):
    return Column('source_site_id', Integer, ForeignKey('site.site_id'))


  # The site that collected the order -- collectedInfo['site'] in the resulting JSON
  @declared_attr
  def collectedSiteId(cls):
    return Column('collected_site_id', Integer, ForeignKey('site.site_id'))


  # The site that processed the order -- processedInfo['site'] in the resulting JSON
  @declared_attr
  def processedSiteId(cls):
    return Column('processed_site_id', Integer, ForeignKey('site.site_id'))


  # The site that finalized the order -- finalizedInfo['site'] in the resulting JSON
  @declared_attr
  def finalizedSiteId(cls):
    return Column('finalized_site_id', Integer, ForeignKey('site.site_id'))

  @declared_attr
  def restoredSiteId(cls):
    return Column('restored_site_id', Integer, ForeignKey('site.site_id'))

  @declared_attr
  def amendedSiteId(cls):
    return Column('amended_site_id', Integer, ForeignKey('site.site_id'))

  @declared_attr
  def cancelledSiteId(cls):
    return Column('cancelled_site_id', Integer, ForeignKey('site.site_id'))
Пример #16
0
class BiobankDVOrder(Base):
    """
  Direct Volunteer kit order shipment record
  """
    _VIBRENT_ID_SYSTEM = 'http://vibrenthealth.com'
    __tablename__ = 'biobank_dv_order'

    # Primary Key
    id = Column('id',
                Integer,
                primary_key=True,
                autoincrement=True,
                nullable=False)
    # have mysql set the creation data for each new order
    created = Column('created', DateTime, nullable=True)
    # have mysql always update the modified data when the record is changed
    modified = Column('modified', DateTime, nullable=True)
    # Incrementing version, starts at 1 and is incremented on each update.
    version = Column('version', Integer, nullable=False)

    participantId = Column('participant_id',
                           Integer,
                           ForeignKey('participant.participant_id'),
                           nullable=False)

    # identifier/code (system=OrderId)
    order_id = Column('order_id', BigInteger)
    # authored: date supplier was requested to send item.
    order_date = Column('order_date', DateTime)

    #
    # Supplier info
    #
    # supplier
    supplier = Column('supplier', String(80), nullable=True)
    # status
    supplierStatus = Column('supplier_status', String(30), nullable=True)

    #
    # Ordered item information
    #
    # itemReference/Device/DeviceName/Name
    itemName = Column('item_name', String(80), nullable=True)
    # itemReference/Device/Identifier[0] (system=SKU)
    itemSKUCode = Column('item_sku_code', String(80), nullable=True)
    # itemReference/Device/Identifier[1] (system=SNOMED)
    itemSNOMEDCode = Column('item_snomed_code', String(80), nullable=True)
    itemQuantity = Column('item_quantity', Integer, default=1)

    #
    # participant ship-to address
    #
    streetAddress1 = Column('street_address_1', String(255))
    streetAddress2 = Column('street_address_2', String(255))
    city = Column('city', String(255))
    stateId = Column('state_id', Integer, ForeignKey('code.code_id'))
    zipCode = Column('zip_code', String(10))

    #
    # biobank ship-to address
    #
    biobankStreetAddress1 = Column('biobank_street_address_1', String(255))
    biobankStreetAddress2 = Column('biobank_street_address_2', String(255))
    biobankCity = Column('biobank_city', String(255))
    biobankStateId = Column('biobank_state_id', Integer,
                            ForeignKey('code.code_id'))
    biobankZipCode = Column('biobank_zip_code', String(10))

    # occurenceDateTime
    shipmentLastUpdate = Column('shipment_last_update',
                                DateTime,
                                nullable=True)

    # To participant tracking id. identifier/code (system=trackingId).
    trackingId = Column('tracking_id', String(80), nullable=True)
    # To biobank tracking id. partOf/identifier/code (system=trackingId).
    biobankTrackingId = Column('biobank_tracking_id',
                               String(80),
                               nullable=True)

    #
    # PTSC extensions
    #
    # order-type
    orderType = Column('order_type', String(80), nullable=True)
    # fullfillment-status
    orderStatus = Column('order_status',
                         Enum(OrderShipmentStatus),
                         default=OrderShipmentStatus.UNSET)
    # carrier
    shipmentCarrier = Column('shipment_carrier', String(80), nullable=True)
    # expected-delivery-date
    shipmentEstArrival = Column('shipment_est_arrival',
                                DateTime,
                                nullable=True)
    # tracking-status
    shipmentStatus = Column('shipment_status',
                            Enum(OrderShipmentTrackingStatus),
                            default=OrderShipmentTrackingStatus.UNSET)

    # barcode
    barcode = Column('barcode', String(80), nullable=True)

    #
    # Mayolink API response
    #
    biobankOrderId = Column('biobank_order_id',
                            String(80),
                            ForeignKey('biobank_order.biobank_order_id'),
                            unique=True,
                            nullable=True)

    biobankStatus = Column('biobank_status', String(30), nullable=True)
    biobankReceived = Column('biobank_received', UTCDateTime6, nullable=True)
    biobankRequisition = Column('biobank_requisition', Text, nullable=True)

    __table_args__ = (UniqueConstraint('participant_id',
                                       'order_id',
                                       name='uidx_partic_id_order_id'), )
Пример #17
0
class BiobankStoredSample(Base):
  """Physical sampels which have been reported as received at Biobank.

  Each participant has an associated list of samples. Biobank uploads a list of all received
  samples periodically, and we update our list of stored samples to match. The output is a
  reconciliation report of ordered and stored samples; see BiobankOrder.

  Note that additional columns appear in the CSV uploaded from Biobank but are not persisted since
  they are unused in the reconciliation report; we also only exclude child samples.

  Additional field information from biobank:

    A sample family (family_id) is created upon a parent tube being created. The family
    contains study, visit, parent specimen information and others. Knowing the study,
    visit and specimen information we are able to capture the test code value from the
    study build information.  Each sample is then linked to the family by their family id.

    Order Identifier (biobank_order_identifier.value) is the unique id generated for
    each order placed into MayoLink. This value has two different phases, before Aug
    2018 and after.

    Sample Order Id (biobank_ordered_sample.order_id) is the unique id generated by MayoLink as a
    internal primary key value.

    Sample Id (biobank_stored_sample_id) is the unique specimen id. Each sample created has a
    unique Id. Sample ids are contained within a family. Family is created at same time the
    parent tube is created.

    Specimen Id for this project now is the order id plus an extra 4 numeric values.
    First 2 represent study and the next two are identifying the test we are receiving.


  """
  __tablename__ = 'biobank_stored_sample'
  # A unique ID assigned by Biobank for the sample. (AKA "RLIMS Sample ID.)
  # We omit autoincrement=False to avoid warnings & instead validate clients provide an ID upstream.
  biobankStoredSampleId = Column('biobank_stored_sample_id', String(80), primary_key=True)

  # The participant the sample is associated to. We use Biobank's ID for streamlined importing.
  biobankId = Column('biobank_id', Integer, ForeignKey('participant.biobank_id'))

  # The biobank order identifier. to enable joining on reconciliation report.
  biobankOrderIdentifier = Column('biobank_order_identifier', String(80), nullable=False)
  # Which test was performed to produce this sample (ex: "1UR10" for blood draw). Rarely, the same
  # test may be performed multiple times for the same participant.
  test = Column('test', String(80), nullable=False, index=True)

  # Timestamp when Biobank finished receiving/preparing the sample (status changed from "In Prep"
  # to "In Circulation" in Mayo). This is the end time used for order-to-sample latency measurement.
  # We may receive samples before they are confirmed (and see a confirmed date added later).
  confirmed = Column('confirmed', UTCDateTime)

  # Timestamp when Biobank received / created the sample.
  created = Column('created', UTCDateTime)

  # sample status, includes all the statuses from SampleStatus Enum.
  status = Column('status', Enum(SampleStatus), default=SampleStatus.RECEIVED)

  # Timestamp sample was disposed.
  disposed = Column('disposed', UTCDateTime)

  # Sample family ID
  family_id = Column('family_id', String(80), nullable=True)

  __table_args__ = (
    Index('ix_boi_test', 'biobank_order_identifier', 'test'),
  )
class ParticipantSummary(Base):
    """Summary fields extracted from participant data (combined from multiple tables).
  Consented participants only."""
    __tablename__ = 'participant_summary'
    participantId = Column('participant_id',
                           Integer,
                           ForeignKey('participant.participant_id'),
                           primary_key=True,
                           autoincrement=False)
    biobankId = Column('biobank_id', Integer, nullable=False)
    lastModified = Column('last_modified', UTCDateTime6)
    # PTC string fields will generally be limited to 255 chars; set our field lengths accordingly to
    # ensure that long values can be inserted.
    firstName = Column('first_name', String(255), nullable=False)
    middleName = Column('middle_name', String(255))
    lastName = Column('last_name', String(255), nullable=False)
    zipCode = Column('zip_code', String(10))
    stateId = Column('state_id', Integer, ForeignKey('code.code_id'))
    city = Column('city', String(255))
    streetAddress = Column('street_address', String(255))
    streetAddress2 = Column('street_address2', String(255))
    phoneNumber = Column('phone_number', String(80))
    loginPhoneNumber = Column('login_phone_number', String(80))
    email = Column('email', String(255))
    primaryLanguage = Column('primary_language', String(80))
    recontactMethodId = Column('recontact_method_id', Integer,
                               ForeignKey('code.code_id'))
    # deprecated - will remove languageId in the future
    languageId = Column('language_id', Integer, ForeignKey('code.code_id'))
    dateOfBirth = Column('date_of_birth', Date)
    genderIdentityId = Column('gender_identity_id', Integer,
                              ForeignKey('code.code_id'))
    sexId = Column('sex_id', Integer, ForeignKey('code.code_id'))
    sexualOrientationId = Column('sexual_orientation_id', Integer,
                                 ForeignKey('code.code_id'))
    educationId = Column('education_id', Integer, ForeignKey('code.code_id'))
    incomeId = Column('income_id', Integer, ForeignKey('code.code_id'))
    enrollmentStatus = Column('enrollment_status',
                              Enum(EnrollmentStatus),
                              default=EnrollmentStatus.INTERESTED)
    race = Column('race', Enum(Race), default=Race.UNSET)
    physicalMeasurementsStatus = Column(
        'physical_measurements_status',
        Enum(PhysicalMeasurementsStatus),
        default=PhysicalMeasurementsStatus.UNSET)
    # The first time that physical measurements were submitted for the participant.
    physicalMeasurementsTime = Column('physical_measurements_time',
                                      UTCDateTime)
    # The time that physical measurements were finalized (before submission to the RDR)
    physicalMeasurementsFinalizedTime = Column(
        'physical_measurements_finalized_time', UTCDateTime)
    physicalMeasurementsCreatedSiteId = Column(
        'physical_measurements_created_site_id', Integer,
        ForeignKey('site.site_id'))
    physicalMeasurementsFinalizedSiteId = Column(
        'physical_measurements_finalized_site_id', Integer,
        ForeignKey('site.site_id'))
    numberDistinctVisits = Column('number_distinct_visits', Integer, default=0)
    signUpTime = Column('sign_up_time', UTCDateTime)

    # The time that this participant become a member
    enrollmentStatusMemberTime = Column('enrollment_status_member_time',
                                        UTCDateTime)
    # The time when we get the first stored sample
    enrollmentStatusCoreStoredSampleTime = Column(
        'enrollment_status_core_stored_sample_time', UTCDateTime)
    # The time when we get a DNA order
    enrollmentStatusCoreOrderedSampleTime = Column(
        'enrollment_status_core_ordered_sample_time', UTCDateTime)

    # Fields for which questionnaires have been submitted, and at what times.
    consentForStudyEnrollment = Column('consent_for_study_enrollment',
                                       Enum(QuestionnaireStatus),
                                       default=QuestionnaireStatus.UNSET)
    consentForStudyEnrollmentTime = Column('consent_for_study_enrollment_time',
                                           UTCDateTime)
    consentForStudyEnrollmentAuthored = Column(
        'consent_for_study_enrollment_authored', UTCDateTime)
    consentForElectronicHealthRecords = Column(
        'consent_for_electronic_health_records',
        Enum(QuestionnaireStatus),
        default=QuestionnaireStatus.UNSET)
    consentForElectronicHealthRecordsTime = Column(
        'consent_for_electronic_health_records_time', UTCDateTime)
    consentForElectronicHealthRecordsAuthored = Column(
        'consent_for_electronic_health_records_authored', UTCDateTime)
    consentForDvElectronicHealthRecordsSharing = Column(
        'consent_for_dv_electronic_health_records_sharing',
        Enum(QuestionnaireStatus),
        default=QuestionnaireStatus.UNSET)
    consentForDvElectronicHealthRecordsSharingTime = Column(
        'consent_for_dv_electronic_health_records_sharing_time', UTCDateTime)
    consentForDvElectronicHealthRecordsSharingAuthored = Column(
        'consent_for_dv_electronic_health_records_sharing_authored',
        UTCDateTime)
    consentForCABoR = Column('consent_for_cabor',
                             Enum(QuestionnaireStatus),
                             default=QuestionnaireStatus.UNSET)
    consentForCABoRTime = Column('consent_for_cabor_time', UTCDateTime)
    consentForCABoRAuthored = Column('consent_for_cabor_authored', UTCDateTime)
    questionnaireOnOverallHealth = Column('questionnaire_on_overall_health',
                                          Enum(QuestionnaireStatus),
                                          default=QuestionnaireStatus.UNSET)
    questionnaireOnOverallHealthTime = Column(
        'questionnaire_on_overall_health_time', UTCDateTime)
    questionnaireOnOverallHealthAuthored = Column(
        'questionnaire_on_overall_health_authored', UTCDateTime)
    questionnaireOnLifestyle = Column('questionnaire_on_lifestyle',
                                      Enum(QuestionnaireStatus),
                                      default=QuestionnaireStatus.UNSET)
    questionnaireOnLifestyleTime = Column('questionnaire_on_lifestyle_time',
                                          UTCDateTime)
    questionnaireOnLifestyleAuthored = Column(
        'questionnaire_on_lifestyle_authored', UTCDateTime)
    questionnaireOnTheBasics = Column('questionnaire_on_the_basics',
                                      Enum(QuestionnaireStatus),
                                      default=QuestionnaireStatus.UNSET)
    questionnaireOnTheBasicsTime = Column('questionnaire_on_the_basics_time',
                                          UTCDateTime)
    questionnaireOnTheBasicsAuthored = Column(
        'questionnaire_on_the_basics_authored', UTCDateTime)
    questionnaireOnHealthcareAccess = Column(
        'questionnaire_on_healthcare_access',
        Enum(QuestionnaireStatus),
        default=QuestionnaireStatus.UNSET)
    questionnaireOnHealthcareAccessTime = Column(
        'questionnaire_on_healthcare_access_time', UTCDateTime)
    questionnaireOnHealthcareAccessAuthored = Column(
        'questionnaire_on_healthcare_access_authored', UTCDateTime)
    questionnaireOnMedicalHistory = Column('questionnaire_on_medical_history',
                                           Enum(QuestionnaireStatus),
                                           default=QuestionnaireStatus.UNSET)
    questionnaireOnMedicalHistoryTime = Column(
        'questionnaire_on_medical_history_time', UTCDateTime)
    questionnaireOnMedicalHistoryAuthored = Column(
        'questionnaire_on_medical_history_authored', UTCDateTime)
    questionnaireOnMedications = Column('questionnaire_on_medications',
                                        Enum(QuestionnaireStatus),
                                        default=QuestionnaireStatus.UNSET)
    questionnaireOnMedicationsTime = Column(
        'questionnaire_on_medications_time', UTCDateTime)
    questionnaireOnMedicationsAuthored = Column(
        'questionnaire_on_medications_authored', UTCDateTime)
    questionnaireOnFamilyHealth = Column('questionnaire_on_family_health',
                                         Enum(QuestionnaireStatus),
                                         default=QuestionnaireStatus.UNSET)
    questionnaireOnFamilyHealthTime = Column(
        'questionnaire_on_family_health_time', UTCDateTime)
    questionnaireOnFamilyHealthAuthored = Column(
        'questionnaire_on_family_health_authored', UTCDateTime)

    # Fields for which samples have been received, and at what times.
    sampleStatus1SST8 = Column('sample_status_1sst8',
                               Enum(SampleStatus),
                               default=SampleStatus.UNSET)
    sampleStatus1SST8Time = Column('sample_status_1sst8_time', UTCDateTime)
    sampleStatus2SST8 = Column('sample_status_2sst8',
                               Enum(SampleStatus),
                               default=SampleStatus.UNSET)
    sampleStatus2SST8Time = Column('sample_status_2sst8_time', UTCDateTime)
    sampleStatus1SS08 = Column('sample_status_1ss08',
                               Enum(SampleStatus),
                               default=SampleStatus.UNSET)
    sampleStatus1SS08Time = Column('sample_status_1ss08_time', UTCDateTime)
    sampleStatus1PST8 = Column('sample_status_1pst8',
                               Enum(SampleStatus),
                               default=SampleStatus.UNSET)
    sampleStatus1PST8Time = Column('sample_status_1pst8_time', UTCDateTime)
    sampleStatus2PST8 = Column('sample_status_2pst8',
                               Enum(SampleStatus),
                               default=SampleStatus.UNSET)
    sampleStatus2PST8Time = Column('sample_status_2pst8_time', UTCDateTime)
    sampleStatus1PS08 = Column('sample_status_1ps08',
                               Enum(SampleStatus),
                               default=SampleStatus.UNSET)
    sampleStatus1PS08Time = Column('sample_status_1ps08_time', UTCDateTime)
    sampleStatus1HEP4 = Column('sample_status_1hep4',
                               Enum(SampleStatus),
                               default=SampleStatus.UNSET)
    sampleStatus1HEP4Time = Column('sample_status_1hep4_time', UTCDateTime)
    sampleStatus1ED04 = Column('sample_status_1ed04',
                               Enum(SampleStatus),
                               default=SampleStatus.UNSET)
    sampleStatus1ED04Time = Column('sample_status_1ed04_time', UTCDateTime)
    sampleStatus1ED10 = Column('sample_status_1ed10',
                               Enum(SampleStatus),
                               default=SampleStatus.UNSET)
    sampleStatus1ED10Time = Column('sample_status_1ed10_time', UTCDateTime)
    sampleStatus2ED10 = Column('sample_status_2ed10',
                               Enum(SampleStatus),
                               default=SampleStatus.UNSET)
    sampleStatus2ED10Time = Column('sample_status_2ed10_time', UTCDateTime)
    sampleStatus1UR10 = Column('sample_status_1ur10',
                               Enum(SampleStatus),
                               default=SampleStatus.UNSET)
    sampleStatus1UR10Time = Column('sample_status_1ur10_time', UTCDateTime)
    sampleStatus1UR90 = Column('sample_status_1ur90',
                               Enum(SampleStatus),
                               default=SampleStatus.UNSET)
    sampleStatus1UR90Time = Column('sample_status_1ur90_time', UTCDateTime)
    sampleStatus1SAL = Column('sample_status_1sal',
                              Enum(SampleStatus),
                              default=SampleStatus.UNSET)
    sampleStatus1SALTime = Column('sample_status_1sal_time', UTCDateTime)
    sampleStatus1SAL2 = Column('sample_status_1sal2',
                               Enum(SampleStatus),
                               default=SampleStatus.UNSET)
    sampleStatus1SAL2Time = Column('sample_status_1sal2_time', UTCDateTime)
    sampleStatus1ED02 = Column('sample_status_1ed02',
                               Enum(SampleStatus),
                               default=SampleStatus.UNSET)
    sampleStatus1ED02Time = Column('sample_status_1ed02_time', UTCDateTime)
    sampleStatus1CFD9 = Column('sample_status_1cfd9',
                               Enum(SampleStatus),
                               default=SampleStatus.UNSET)
    sampleStatus1CFD9Time = Column('sample_status_1cfd9_time', UTCDateTime)
    sampleStatus1PXR2 = Column('sample_status_1pxr2',
                               Enum(SampleStatus),
                               default=SampleStatus.UNSET)
    sampleStatus1PXR2Time = Column('sample_status_1pxr2_time', UTCDateTime)

    # Sample fields for Direct Volunteers
    # These are deprecated in favor of using the standard samplestatus2sal2, etc.
    sampleStatusDV1SAL2 = Column('sample_status_dv_1sal2',
                                 Enum(SampleStatus),
                                 default=SampleStatus.UNSET)
    sampleStatusDV1SAL2Time = Column('sample_status_dv_1sal2_time',
                                     UTCDateTime)

    sampleOrderStatusDV1SAL2 = Column('sample_order_status_dv_1sal2',
                                      Enum(OrderStatus),
                                      default=OrderStatus.UNSET)
    sampleOrderStatusDV1SAL2Time = Column('sample_order_status_dv_1sal2_time',
                                          UTCDateTime)

    # Fields for which samples have been ordered, and at what times.
    sampleOrderStatus1SST8 = Column('sample_order_status_1sst8',
                                    Enum(OrderStatus),
                                    default=OrderStatus.UNSET)
    sampleOrderStatus1SST8Time = Column('sample_order_status_1sst8_time',
                                        UTCDateTime)
    sampleOrderStatus2SST8 = Column('sample_order_status_2sst8',
                                    Enum(OrderStatus),
                                    default=OrderStatus.UNSET)
    sampleOrderStatus2SST8Time = Column('sample_order_status_2sst8_time',
                                        UTCDateTime)
    sampleOrderStatus1SS08 = Column('sample_order_status_1ss08',
                                    Enum(OrderStatus),
                                    default=OrderStatus.UNSET)
    sampleOrderStatus1SS08Time = Column('sample_order_status_1ss08_time',
                                        UTCDateTime)
    sampleOrderStatus1PST8 = Column('sample_order_status_1pst8',
                                    Enum(OrderStatus),
                                    default=OrderStatus.UNSET)
    sampleOrderStatus1PST8Time = Column('sample_order_status_1pst8_time',
                                        UTCDateTime)
    sampleOrderStatus2PST8 = Column('sample_order_status_2pst8',
                                    Enum(OrderStatus),
                                    default=OrderStatus.UNSET)
    sampleOrderStatus2PST8Time = Column('sample_order_status_2pst8_time',
                                        UTCDateTime)
    sampleOrderStatus1PS08 = Column('sample_order_status_1ps08',
                                    Enum(OrderStatus),
                                    default=OrderStatus.UNSET)
    sampleOrderStatus1PS08Time = Column('sample_order_status_1ps08_time',
                                        UTCDateTime)
    sampleOrderStatus1HEP4 = Column('sample_order_status_1hep4',
                                    Enum(OrderStatus),
                                    default=OrderStatus.UNSET)
    sampleOrderStatus1HEP4Time = Column('sample_order_status_1hep4_time',
                                        UTCDateTime)
    sampleOrderStatus1ED04 = Column('sample_order_status_1ed04',
                                    Enum(OrderStatus),
                                    default=OrderStatus.UNSET)
    sampleOrderStatus1ED04Time = Column('sample_order_status_1ed04_time',
                                        UTCDateTime)
    sampleOrderStatus1ED10 = Column('sample_order_status_1ed10',
                                    Enum(OrderStatus),
                                    default=OrderStatus.UNSET)
    sampleOrderStatus1ED10Time = Column('sample_order_status_1ed10_time',
                                        UTCDateTime)
    sampleOrderStatus2ED10 = Column('sample_order_status_2ed10',
                                    Enum(OrderStatus),
                                    default=OrderStatus.UNSET)
    sampleOrderStatus2ED10Time = Column('sample_order_status_2ed10_time',
                                        UTCDateTime)
    sampleOrderStatus1UR10 = Column('sample_order_status_1ur10',
                                    Enum(OrderStatus),
                                    default=OrderStatus.UNSET)
    sampleOrderStatus1UR10Time = Column('sample_order_status_1ur10_time',
                                        UTCDateTime)
    sampleOrderStatus1UR90 = Column('sample_order_status_1ur90',
                                    Enum(OrderStatus),
                                    default=OrderStatus.UNSET)
    sampleOrderStatus1UR90Time = Column('sample_order_status_1ur90_time',
                                        UTCDateTime)
    sampleOrderStatus1SAL = Column('sample_order_status_1sal',
                                   Enum(OrderStatus),
                                   default=OrderStatus.UNSET)
    sampleOrderStatus1SALTime = Column('sample_order_status_1sal_time',
                                       UTCDateTime)
    sampleOrderStatus1SAL2 = Column('sample_order_status_1sal2',
                                    Enum(OrderStatus),
                                    default=OrderStatus.UNSET)
    sampleOrderStatus1SAL2Time = Column('sample_order_status_1sal2_time',
                                        UTCDateTime)

    sampleOrderStatus1ED02 = Column('sample_order_status_1ed02',
                                    Enum(OrderStatus),
                                    default=OrderStatus.UNSET)
    sampleOrderStatus1ED02Time = Column('sample_order_status_1ed02_time',
                                        UTCDateTime)
    sampleOrderStatus1CFD9 = Column('sample_order_status_1cfd9',
                                    Enum(OrderStatus),
                                    default=OrderStatus.UNSET)
    sampleOrderStatus1CFD9Time = Column('sample_order_status_1cfd9_time',
                                        UTCDateTime)
    sampleOrderStatus1PXR2 = Column('sample_order_status_1pxr2',
                                    Enum(OrderStatus),
                                    default=OrderStatus.UNSET)
    sampleOrderStatus1PXR2Time = Column('sample_order_status_1pxr2_time',
                                        UTCDateTime)

    numCompletedBaselinePPIModules = Column(
        'num_completed_baseline_ppi_modules', SmallInteger, default=0)
    numCompletedPPIModules = Column('num_completed_ppi_modules',
                                    SmallInteger,
                                    default=0)

    # The number of BiobankStoredSamples recorded for this participant, limited to those samples
    # where testCode is one of the baseline tests (listed in the config).
    numBaselineSamplesArrived = Column('num_baseline_samples_arrived',
                                       SmallInteger,
                                       default=0)
    samplesToIsolateDNA = Column('samples_to_isolate_dna',
                                 Enum(SampleStatus),
                                 default=SampleStatus.UNSET)
    # Whether biospecimens have been finalized or not, and the time at which they were
    # finalized.
    biospecimenStatus = Column('biospecimen_status',
                               Enum(OrderStatus),
                               default=OrderStatus.UNSET)
    biospecimenOrderTime = Column('biospecimen_order_time', UTCDateTime)
    biospecimenSourceSiteId = Column('biospecimen_source_site_id', Integer,
                                     ForeignKey('site.site_id'))
    biospecimenCollectedSiteId = Column('biospecimen_collected_site_id',
                                        Integer, ForeignKey('site.site_id'))
    biospecimenProcessedSiteId = Column('biospecimen_processed_site_id',
                                        Integer, ForeignKey('site.site_id'))
    biospecimenFinalizedSiteId = Column('biospecimen_finalized_site_id',
                                        Integer, ForeignKey('site.site_id'))

    # EHR status related columns
    ehrStatus = Column('ehr_status',
                       Enum(EhrStatus),
                       default=EhrStatus.NOT_PRESENT)
    ehrReceiptTime = Column('ehr_receipt_time', UTCDateTime)
    ehrUpdateTime = Column('ehr_update_time', UTCDateTime)

    # Withdrawal from the study of the participant's own accord.
    withdrawalStatus = Column('withdrawal_status',
                              Enum(WithdrawalStatus),
                              nullable=False)
    withdrawalReason = Column('withdrawal_reason', Enum(WithdrawalReason))
    withdrawalTime = Column('withdrawal_time', UTCDateTime)
    withdrawalReasonJustification = Column('withdrawal_reason_justification',
                                           UnicodeText)

    suspensionStatus = Column('suspension_status',
                              Enum(SuspensionStatus),
                              nullable=False)
    suspensionTime = Column('suspension_time', UTCDateTime)

    participant = relationship("Participant",
                               back_populates="participantSummary")

    @declared_attr
    def hpoId(cls):
        return Column('hpo_id',
                      Integer,
                      ForeignKey('hpo.hpo_id'),
                      nullable=False)

    @declared_attr
    def organizationId(cls):
        return Column('organization_id', Integer,
                      ForeignKey('organization.organization_id'))

    @declared_attr
    def siteId(cls):
        return Column('site_id', Integer, ForeignKey('site.site_id'))