"""Seed published lab reference values from cited public pediatric references. Sources (cited per row): - University of Iowa Health Care Pathology Handbook, Pediatric Reference Ranges https://www.healthcare.uiowa.edu/path_handbook/Appendix/Heme/PEDIATRIC_NORMALS.html - PediRounds Pediatric Laboratory Reference Ranges (reviewed by a paediatric critical care specialist) https://www.pedirounds.com/lab-values/ - Valley Children's HealthHub (ammonia) https://health.valleychildrens.org/ - AAP Pediatrics 2018 CSF reference values (via PediRounds CSF summary) Idempotent: existing (group, name, age_group) rows are left untouched. """ import sys from app.database import SessionLocal from app.models.lab_reference import LabReference from app.models.user import User UI = "University of Iowa Health Care Pathology Handbook — Pediatric Reference Ranges" UI_URL = "https://www.healthcare.uiowa.edu/path_handbook/Appendix/Heme/PEDIATRIC_NORMALS.html" PEDI = "PediRounds — Paediatric Laboratory Reference Ranges (reviewed paediatric critical care specialist)" PEDI_URL = "https://www.pedirounds.com/lab-values/" VALLEY = "Valley Children's Pediatric HealthHub — Ammonia reference ranges" VALLEY_URL = "https://health.valleychildrens.org/hematology/diagnostico/ammonia" CSF_SRC = "PediRounds CSF summary; AAP Pediatrics 2018 CSF reference values for young infants" CSF_URL = "https://publications.aap.org/pediatrics/article/141/3/e20173405/37649/Cerebrospinal-Fluid-Reference-Values-for-Young" ROWS = [ # ── Hematology (UI Health Care, conventional units) ───────────────── ("Hematology", "Hemoglobin", "13.4–19.9", "g/dL", "0–1 month", "Whole blood", UI, UI_URL), ("Hematology", "Hemoglobin", "10.7–17.1", "g/dL", "1–2 months", "Whole blood", UI, UI_URL), ("Hematology", "Hemoglobin", "9.0–14.1", "g/dL", "2–3 months", "Whole blood", UI, UI_URL), ("Hematology", "Hemoglobin", "9.5–14.1", "g/dL", "3–6 months", "Whole blood", UI, UI_URL), ("Hematology", "Hemoglobin", "11.3–14.1", "g/dL", "6 months–1 year", "Whole blood", UI, UI_URL), ("Hematology", "Hemoglobin", "10.9–15.0", "g/dL", "1–5 years", "Whole blood", UI, UI_URL), ("Hematology", "Hemoglobin", "11.9–15.0", "g/dL", "5–11 years", "Whole blood", UI, UI_URL), ("Hematology", "Hemoglobin", "12.7–17.7 (M) / 11.9–15.0 (F)", "g/dL", "11–18 years", "Whole blood", UI, UI_URL), ("Hematology", "Hematocrit", "42–65", "%", "0–1 month", "Whole blood", UI, UI_URL), ("Hematology", "Hematocrit", "33–55", "%", "1–2 months", "Whole blood", UI, UI_URL), ("Hematology", "Hematocrit", "28–41", "%", "2–3 months", "Whole blood", UI, UI_URL), ("Hematology", "Hematocrit", "29–41", "%", "3–6 months", "Whole blood", UI, UI_URL), ("Hematology", "Hematocrit", "31–41", "%", "6 months–1 year", "Whole blood", UI, UI_URL), ("Hematology", "Hematocrit", "31–44", "%", "1–5 years", "Whole blood", UI, UI_URL), ("Hematology", "Hematocrit", "35–44", "%", "5–11 years", "Whole blood", UI, UI_URL), ("Hematology", "Hematocrit", "37–48 (M) / 34–44 (F)", "%", "11–18 years", "Whole blood", UI, UI_URL), ("Hematology", "White cell count", "9,000–30,000", "/mm³", "0–1 month", "Whole blood", UI, UI_URL), ("Hematology", "White cell count", "5,000–19,500", "/mm³", "1–3 months", "Whole blood", UI, UI_URL), ("Hematology", "White cell count", "6,000–17,500", "/mm³", "3 months–1 year", "Whole blood", UI, UI_URL), ("Hematology", "White cell count", "6,000–17,000", "/mm³", "1–2 years", "Whole blood", UI, UI_URL), ("Hematology", "White cell count", "5,500–15,500", "/mm³", "2–4 years", "Whole blood", UI, UI_URL), ("Hematology", "Platelets", "150–400", "×10³/mm³", "All ages", "Whole blood", PEDI, PEDI_URL), ("Hematology", "Neutrophils", "1,000–20,000", "/mm³", "0–1 month", "Whole blood", UI, UI_URL), ("Hematology", "Neutrophils", "1,500–8,500", "/mm³", "6 months–5 years", "Whole blood", UI, UI_URL), ("Hematology", "Neutrophils", "1,700–7,500", "/mm³", "5–18 years", "Whole blood", UI, UI_URL), ("Hematology", "Lymphocytes", "2,000–11,000", "/mm³", "0–1 month", "Whole blood", UI, UI_URL), ("Hematology", "Lymphocytes", "4,000–10,500", "/mm³", "6 months–1 year", "Whole blood", UI, UI_URL), ("Hematology", "Lymphocytes", "2,000–8,000", "/mm³", "2–5 years", "Whole blood", UI, UI_URL), ("Hematology", "MCV", "88–123", "fL", "0–1 month", "Whole blood", UI, UI_URL), ("Hematology", "MCV", "74–108", "fL", "3–6 months", "Whole blood", UI, UI_URL), ("Hematology", "MCV", "70–85", "fL", "6 months–1 year", "Whole blood", UI, UI_URL), ("Hematology", "Reticulocytes", "0.5–1.5", "%", "All ages (higher in newborn)", "Whole blood", PEDI, PEDI_URL), # ── Chemistries ───────────────────────────────────────────────────── ("Chemistries", "Sodium", "135–145", "mmol/L", ">10 days", "Plasma", PEDI, PEDI_URL), ("Chemistries", "Potassium", "3.5–6.0", "mEq/L", "<10 days", "Plasma", UI, UI_URL), ("Chemistries", "Potassium", "3.5–5.0", "mEq/L", ">10 days", "Plasma", UI, UI_URL), ("Chemistries", "Chloride", "98–106", "mmol/L", "All ages", "Plasma", PEDI, PEDI_URL), ("Chemistries", "Bicarbonate (CO2)", "18–27", "mEq/L", "All ages", "Plasma", UI, UI_URL), ("Chemistries", "Bicarbonate", "22–26", "mmol/L", "All ages", "Plasma", PEDI, PEDI_URL), ("Chemistries", "Urea nitrogen (BUN)", "7–18 (urea 2.5–6.5 mmol/L)", "mg/dL", "All ages", "Plasma", PEDI, PEDI_URL), ("Chemistries", "Creatinine", "0.2–0.9", "mg/dL", "Neonate", "Plasma", UI, UI_URL), ("Chemistries", "Creatinine", "0.2–0.4", "mg/dL", "2–12 months", "Plasma", UI, UI_URL), ("Chemistries", "Creatinine", "0.2–0.5", "mg/dL", "1–2 years", "Plasma", UI, UI_URL), ("Chemistries", "Creatinine", "0.3–0.7", "mg/dL", "3–6 years", "Plasma", UI, UI_URL), ("Chemistries", "Creatinine", "0.3–0.9", "mg/dL", "11–12 years", "Plasma", UI, UI_URL), ("Chemistries", "Creatinine", "0.4–0.9", "mg/dL", "13–15 years", "Plasma", UI, UI_URL), ("Chemistries", "Glucose", "50–99", "mg/dL", "0–1 month", "Plasma", UI, UI_URL), ("Chemistries", "Glucose", "65–99", "mg/dL", ">1 month", "Plasma", UI, UI_URL), ("Chemistries", "Calcium (total)", "8.5–10.6", "mg/dL", "Birth–30 days", "Plasma", UI, UI_URL), ("Chemistries", "Calcium (total)", "8.7–10.5", "mg/dL", "31 days–1 year", "Plasma", UI, UI_URL), ("Chemistries", "Calcium (total)", "8.8–10.6", "mg/dL", "1–6 years", "Plasma", UI, UI_URL), ("Chemistries", "Calcium (ionized)", "4.2–5.9", "mg/dL", "Neonate", "Plasma", UI, UI_URL), ("Chemistries", "Magnesium", "1.6–2.4 (0.7–1.0 mmol/L)", "mg/dL", "All ages", "Plasma", PEDI, PEDI_URL), ("Chemistries", "Phosphate", "4.2–9.0", "mg/dL", "Newborn–11 months", "Plasma", UI, UI_URL), ("Chemistries", "Phosphate", "3.2–6.3", "mg/dL", "12 months–15 years", "Plasma", UI, UI_URL), ("Chemistries", "Albumin", "2.8–4.4", "g/dL", "0–4 days", "Plasma", UI, UI_URL), ("Chemistries", "Albumin", "3.8–5.4", "g/dL", "4 days–14 years", "Plasma", UI, UI_URL), ("Chemistries", "Total protein", "4.1–6.3", "g/dL", "Birth–31 days", "Plasma", UI, UI_URL), ("Chemistries", "Total protein", "5.7–8.0", "g/dL", "1–18 years", "Plasma", UI, UI_URL), ("Chemistries", "Bilirubin (total)", "<1.8", "mg/dL", "Cord blood (24 h)", "Serum", UI, UI_URL), ("Chemistries", "Bilirubin (total)", "≤6.0", "mg/dL", "Term, 24 h", "Serum", UI, UI_URL), ("Chemistries", "Bilirubin (total)", "≤7.0", "mg/dL", "Term, 48 h", "Serum", UI, UI_URL), ("Chemistries", "Bilirubin (total)", "≤12.0", "mg/dL", "3–5 days", "Serum", UI, UI_URL), ("Chemistries", "Bilirubin (total)", "<1.0", "mg/dL", "1 month–adult", "Serum", UI, UI_URL), ("Chemistries", "ALT", "<40", "U/L", "All ages", "Plasma", PEDI, PEDI_URL), ("Chemistries", "AST", "<45", "U/L", "All ages (higher in infants)", "Plasma", PEDI, PEDI_URL), ("Chemistries", "GGT", "<55", "U/L", "Child (high in neonates)", "Plasma", PEDI, PEDI_URL), ("Chemistries", "Alkaline phosphatase", "75–316 (M) / 48–406 (F)", "U/L", "1–30 days", "Plasma", UI, UI_URL), ("Chemistries", "Alkaline phosphatase", "82–383 (M) / 124–341 (F)", "U/L", "31 days–1 year", "Plasma", UI, UI_URL), ("Chemistries", "Alkaline phosphatase", "104–345 (M) / 108–317 (F)", "U/L", "1–3 years", "Plasma", UI, UI_URL), ("Chemistries", "Ammonia", "170–341", "µg/dL", "0–10 days (enzymatic)", "Plasma", VALLEY, VALLEY_URL), ("Chemistries", "Ammonia", "68–136", "µg/dL", "10 days–2 years (enzymatic)", "Plasma", VALLEY, VALLEY_URL), ("Chemistries", "Ammonia", "19–60", "µg/dL", ">2 years (enzymatic)", "Plasma", VALLEY, VALLEY_URL), # ── Acid–base / gases ──────────────────────────────────────────────── ("Acid-base / gases", "pH (arterial)", "7.32–7.42", "", "0–1 month", "Arterial blood", UI, UI_URL), ("Acid-base / gases", "pH (arterial)", "7.35–7.45", "", ">1 month", "Arterial blood", UI, UI_URL), ("Acid-base / gases", "pCO2 (arterial)", "30–40", "mmHg", "0–18 years", "Arterial blood", UI, UI_URL), ("Acid-base / gases", "pO2 (arterial)", "60–80", "mmHg", "0–1 month", "Arterial blood", UI, UI_URL), ("Acid-base / gases", "pO2 (arterial)", "80–100", "mmHg", ">1 month", "Arterial blood", UI, UI_URL), ("Acid-base / gases", "Base excess", "−2 to +2", "mmol/L", "All ages", "Blood gas", PEDI, PEDI_URL), ("Acid-base / gases", "Lactate", "<2.0", "mmol/L", "All ages", "Blood", PEDI, PEDI_URL), # ── Coagulation ────────────────────────────────────────────────────── ("Coagulation", "PT", "11–14", "seconds", "All ages", "Plasma", PEDI, PEDI_URL), ("Coagulation", "aPTT", "25–35", "seconds", "All ages", "Plasma", PEDI, PEDI_URL), ("Coagulation", "INR", "0.9–1.2", "", "All ages", "Plasma", PEDI, PEDI_URL), ("Coagulation", "Fibrinogen", "150–400 (1.5–4.0 g/L)", "mg/dL", "All ages", "Plasma", PEDI, PEDI_URL), ("Coagulation", "D-dimer", "<0.5", "mg/L", "All ages (assay-dependent)", "Plasma", PEDI, PEDI_URL), # ── Inflammatory ───────────────────────────────────────────────────── ("Inflammatory", "CRP", "<10 (<1.0 mg/dL)", "mg/L", "All ages", "Serum", PEDI, PEDI_URL), ("Inflammatory", "Procalcitonin", "<0.5", "ng/mL", "All ages", "Serum", PEDI, PEDI_URL), ("Inflammatory", "ESR", "<15", "mm/h", "All ages (varies)", "Blood", PEDI, PEDI_URL), # ── CSF ────────────────────────────────────────────────────────────── ("CSF", "CSF white cell count", "<5 (neonate up to ~20)", "/mm³", "Child vs neonate", "CSF", CSF_SRC, CSF_URL), ("CSF", "CSF protein", "15–40 (neonate up to ~100)", "mg/dL", "Child vs neonate", "CSF", CSF_SRC, CSF_URL), ("CSF", "CSF glucose", "≥2/3 of plasma glucose", "", "All ages", "CSF", CSF_SRC, CSF_URL), # ── Endocrine ──────────────────────────────────────────────────────── ("Endocrine", "TSH", "0.5–5.0", "mU/L", "All ages (higher in neonates)", "Plasma", PEDI, PEDI_URL), ("Endocrine", "Free T4", "12–22", "pmol/L", "All ages", "Plasma", PEDI, PEDI_URL), ("Endocrine", "Cortisol (08:00)", "170–500", "nmol/L", "All ages", "Plasma", PEDI, PEDI_URL), # ── Urine ──────────────────────────────────────────────────────────── ("Urine", "Specific gravity", "1.001–1.035", "", "All ages", "Urine", PEDI, PEDI_URL), ] def main(): db = SessionLocal() try: updated_by = db.query(User.id).filter(User.role.in_(["admin", "moderator"])).order_by(User.id).first() updated_by = updated_by[0] if updated_by else None # Normalize vague population labels on existing rows to match the new seed data. db.query(LabReference).filter(LabReference.age_group == "Child").update({"age_group": "All ages"}, synchronize_session=False) db.query(LabReference).filter(LabReference.age_group == "Child (higher in infants)").update({"age_group": "All ages (higher in infants)"}, synchronize_session=False) db.query(LabReference).filter(LabReference.age_group == "Child (higher in newborn)").update({"age_group": "All ages (higher in newborn)"}, synchronize_session=False) db.query(LabReference).filter(LabReference.age_group == "Child (higher in neonate)").update({"age_group": "All ages (higher in neonates)"}, synchronize_session=False) db.commit() existing = {(row.group, row.name, row.age_group) for row in db.query(LabReference).all()} added = 0 for group, name, ref, units, age, specimen, source, url in ROWS: key = (group, name, age) if key in existing: continue db.add(LabReference( name=name, group=group, reference_range=ref, units=units, age_group=age, specimen=specimen, source=source, source_url=url, is_published=True, updated_by=updated_by, )) added += 1 existing.add(key) db.commit() total = db.query(LabReference).filter(LabReference.is_published.is_(True)).count() print(f"Seeded {added} new published lab references; {total} published total.") finally: db.close() if __name__ == "__main__": sys.exit(main())