Skip to main content

v3

patients record, v3 — canonical aliases.

v3 adds the nullable practitioner_name column to v2 — see schema.py. Consumers and the record registry import from here and never touch the inner module names.

Module​

Submodules​

Functions​

downgrade​

def downgrade(op: Operations) ‑> None:

Migrate patients v3 -> v2 (see the module docstring).

upgrade​

def upgrade(op: Operations) ‑> None:

Migrate patients v2 -> v3 (see the module docstring).

Classes​

NameProvenance​

class NameProvenance(*args, **kwds):

Where a stored display name came from, ranked by how much it is trusted.

patients holds one row per Bitfount patient ID and is not partitioned by project or task, so every run that reaches a patient writes the same row — including runs over different datasources, and runs belonging to another project entirely. Something therefore has to decide which of two names for one patient the row keeps, and the two rendered strings cannot decide it: JANE SMITH and SMITH MRS are both two plausible tokens, and the fact that separates them is not in either string but in what they were derived from.

So the rank is on the source, not the string. RANKS orders them and rank reads that order; bulk_upsert_patients compares ranks and never inspects the names themselves.

Subclasses str so members serialise straight into the name_provenance column without a conversion step.

Variables​

  • static DICOM_PN
  • static EHR
  • static PATIENT_ID_FALLBACK
  • static UNKNOWN
  • static UNPARSED
  • static UNSTRUCTURED
  • rank : int - How much this provenance is trusted, higher being more.

ORM​

class ORM(**kwargs):

SQLAlchemy model for the patients identity table.

A simple constructor that allows initialization from kwargs.

Sets attributes on the constructed instance using the names and values in kwargs.

Only keys that are present as attributes of the instance's class are allowed. These could be, for example, any mapped columns or relationships.

Variables​

  • bitfount_patient_id : Union[sqlalchemy.orm.attributes.InstrumentedAttribute[+_T_co], +_T_co]
  • ehr_patient_id : Union[sqlalchemy.orm.attributes.InstrumentedAttribute[+_T_co], +_T_co]
  • mrns : Union[sqlalchemy.orm.attributes.InstrumentedAttribute[+_T_co], +_T_co]
  • name : Union[sqlalchemy.orm.attributes.InstrumentedAttribute[+_T_co], +_T_co]
  • name_provenance : Union[sqlalchemy.orm.attributes.InstrumentedAttribute[+_T_co], +_T_co]
  • name_raw : Union[sqlalchemy.orm.attributes.InstrumentedAttribute[+_T_co], +_T_co]
  • practitioner_name : Union[sqlalchemy.orm.attributes.InstrumentedAttribute[+_T_co], +_T_co]
  • processed_at : Union[sqlalchemy.orm.attributes.InstrumentedAttribute[+_T_co], +_T_co]
  • run_id : Union[sqlalchemy.orm.attributes.InstrumentedAttribute[+_T_co], +_T_co]
  • tags : Union[sqlalchemy.orm.attributes.InstrumentedAttribute[+_T_co], +_T_co]
  • task_hash : Union[sqlalchemy.orm.attributes.InstrumentedAttribute[+_T_co], +_T_co]

Record​

class Record(**data: Any):

Stored patient identity record (one per Bitfount patient ID).

Attributes

  • bitfount_patient_id: The Bitfount patient ID (primary key).
  • name: Patient display name (always present).
  • name_raw: The unparsed source string name was rendered from, when it came from one — a DICOM PatientName as the file spelled it, for instance. None when no parsing produced the name (an EHR name arrives already split into its own fields; the ID fallback is not a name at all). Kept so a later parsing fix can re-render name without re-reading the file the name came from.
  • name_provenance: What name was derived from, which is what decides whether a later run's name replaces this one.
  • ehr_patient_id: EHR patient ID, or None for non-EHR flows.
  • processed_at: When this row was written.
  • task_hash: Provenance — the run's task hash.
  • run_id: Provenance — the run ID.
  • tags: Arbitrary flat metadata.
  • mrns: The patient's medical record number(s), if known.
  • practitioner_name: The patient's associated medical practitioner, if known.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Variables​

  • static bitfount_patient_id : str
  • static ehr_patient_id : str | None
  • static model_config
  • static mrns : list[str] | None
  • static name : str
  • static name_raw : str | None
  • static practitioner_name : str | None
  • static run_id : str | None
  • static task_hash : str | None