Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
8.1 KiB
Dotazy — přehled lékového záznamu pacienta
Skripty pro zobrazení a export lékového záznamu konkrétního pacienta z MySQL databáze medicus.
Pacient se identifikuje rodným číslem — to se vyhledá v lokální Firebird databázi Medicusu,
odkud se získá příjmení a datum narození, a teprve těmito dvěma hodnotami se najde pacient v MySQL.
Soubory
| Soubor | Co dělá |
|---|---|
prehled_pacienta.py |
Konzolový výpis — lékaři + předpisy pacienta |
prehled_pacienta_excel.py |
Export do formátovaného souboru Excel (.xlsx) |
Nastavení (obě skripty)
Na začátku každého souboru jsou tři proměnné:
RODNE_CISLO = "440802/018" # rodné číslo — funguje s lomítkem i bez: "4408020183"
DATUM_OD = "01.01.2025" # předpisy od tohoto data; None = všechny předpisy
VYSTUP_DIR = None # pouze excel: složka výstupu; None = stejná jako skript
Spuštění
# Konzolový výpis
.venv\Scripts\python.exe Dotazy\prehled_pacienta.py
# Export do Excelu
.venv\Scripts\python.exe Dotazy\prehled_pacienta_excel.py
Zdroje dat
1. Firebird — Medicus (medicus.fdb)
Slouží výhradně k identifikaci pacienta podle rodného čísla.
DSN: localhost:c:\medicus 3\data\medicus.fdb
User: SYSDBA / masterkey
Charset: win1250
Tabulka: KAR
Dotaz:
SELECT KAR.PRIJMENI, KAR.JMENO, KAR.DATNAR
FROM KAR WHERE KAR.RODCIS = ?
Rodné číslo se normalizuje před dotazem — odstraní se lomítko a mezery:
rc = rc.replace("/", "").replace(" ", "").strip()
2. MySQL — databáze medicus
Obsahuje lékové záznamy stažené z eReceptu SÚKL.
Host: 192.168.1.76
User: root
DB: medicus
Pacient se vyhledá podle příjmení a data narození (získaných z Firebirdu):
SELECT id, prijmeni, jmena, datum_narozeni
FROM pacient
WHERE prijmeni = %s AND datum_narozeni = %s
Co se zobrazuje
Část 1 — Předepisující lékaři
Všichni lékaři, kteří pacientovi za celou dobu předepsali alespoň jeden lék,
seřazeni sestupně podle počtu předpisů.
Sloupce: # | Lékař | Odbornost | Pracoviště a adresa | Předpisů
SELECT pr.prijmeni, pr.jmena,
pr.icp,
CONCAT(pr.pzs_nazev, ', ', pr.ulice, ', ', pr.psc, ' ', pr.mesto) AS adresa,
COUNT(*) AS pocet_predpisu
FROM zprava z
JOIN predpis p ON p.zprava_id = z.id
JOIN predepisujici pr ON pr.lekar_kod = p.kod_predepisujiciho
WHERE z.pacient_id = %s
GROUP BY pr.lekar_kod, pr.prijmeni, pr.jmena, pr.icp,
pr.pzs_nazev, pr.ulice, pr.psc, pr.mesto
ORDER BY pocet_predpisu DESC
Část 2 — Všechny předpisy
Předpisy od DATUM_OD, seřazené sestupně dle data vystavení.
Zobrazuje se vydaný lék (z tabulky vydej), nikoli předepsaný název.
Pokud lék nebyl vyzvednut, zobrazí se předepsaný název s příznakem *NV.
Sloupce: # | Datum | Vydaný lék | ATC | Návod | Lékař | Odbornost | Adresa
SELECT p.datum_vystaveni,
COALESCE(v.nazev, p.nazev) AS vydany_lek,
v.nazev IS NULL AS nevyzvednuto,
p.atc,
p.navod,
pr.prijmeni,
pr.jmena,
pr.icp,
CONCAT(pr.pzs_nazev, ', ', pr.ulice, ', ', pr.psc, ' ', pr.mesto) AS adresa
FROM zprava z
JOIN predpis p ON p.zprava_id = z.id
JOIN predepisujici pr ON pr.lekar_kod = p.kod_predepisujiciho
LEFT JOIN vydej v ON v.id_lp_predpis = p.id_lp_predpis
WHERE z.pacient_id = %s
AND p.datum_vystaveni >= %s -- pouze pokud DATUM_OD není None
ORDER BY p.datum_vystaveni DESC
Klíčový princip COALESCE(v.nazev, p.nazev):
v.nazev— název léku, který lékárna skutečně vydala (může být jiná značka než předepsaná)p.nazev— název léku, který lékař předepsal (zobrazí se jen pokud výdej neexistuje →*NV)
Odbornost lékaře
Odbornost se odvozuje z posledních 3 číslic pole predepisujici.icp (IČP pracoviště).
ICP: 09305001 → kód odbornosti: 001 → všeobecné praktické lékařství
ICP: 08006272 → kód odbornosti: 272 → alergologie
ICP: 08075603 → kód odbornosti: 603 → onkologie
Funkce:
def odbornost_z_icp(icp):
if not icp or len(icp) < 3:
return ""
return ODBORNOST.get(icp[-3:], f"odb. {icp[-3:]}")
Pro neznámé kódy se zobrazí odb. XXX (XXX = třímístný kód).
Zdroj dat — tabulky vzp_pracoviste + odbornost (MySQL)
Slovník ODBORNOST se načítá dynamicky při startu skriptu z MySQL:
def _nacti_odbornosti():
conn = pymysql.connect(**DB)
try:
with conn.cursor(pymysql.cursors.Cursor) as cur:
cur.execute("""
SELECT vp.icp, o.nazev
FROM vzp_pracoviste vp
JOIN odbornost o ON o.kod = vp.odbornost
WHERE CURDATE() BETWEEN vp.platnost_od AND vp.platnost_do
ORDER BY vp.platnost_od DESC
""")
result = {}
for icp, nazev in cur.fetchall():
result.setdefault(icp, nazev)
return result
finally:
conn.close()
ODBORNOST = _nacti_odbornosti()
vzp_pracoviste— oficiální číselník VZP (stahován týdně z VZP Point přesimport_vzp_pracoviste.py), obsahuje ~52 000 záznamů s přímou vazbou ICP → kód odbornostiodbornost— číselník názvů odborností importovaný z Firebird tabulkyodborn(360 aktuálně platných kódů)- Vyhledávání probíhá podle plného 8-znakového ICP — spolehlivé i pro pracoviště, která změnila odbornost
- Slovník obsahuje ~43 000 aktuálně platných ICP kódů
Excel export (prehled_pacienta_excel.py)
Soubor se ukládá do stejné složky jako skript (nebo do VYSTUP_DIR).
Pojmenování souborů
LZ_{Prijmeni}_{Jmeno}_{datum_narozeni}.xlsx ← základní
LZ_{Prijmeni}_{Jmeno}_{datum_narozeni}_v2.xlsx ← pokud základní existuje
LZ_{Prijmeni}_{Jmeno}_{datum_narozeni}_v3.xlsx ← atd.
Versioning zabrání přepsání dříve exportovaných souborů.
Vzhled a formátování
| Prvek | Barva | Popis |
|---|---|---|
| Záhlaví (jméno pacienta) | #1F4E79 tmavě modrá |
tučné, 14pt |
| Záhlaví tabulky | #1F4E79 tmavě modrá |
bílý text, 10pt |
| Nadpis sekce | #2E75B6 střední modrá |
bílý text, 11pt |
| Info o pacientovi | #DEEAF1 světle modrá |
datum narozeni, datum tisku, předpisy od |
| Sudé řádky | #EBF3FB velmi světle modrá |
střídání řádků |
| Liché řádky | #FFFFFF bílá |
|
| Nevyzvednuto | #FCE4D6 lososová |
zvýraznění celého řádku |
| Ohraničení | #B8CCE4 světle modrá |
tenká linka |
- Font: Arial ve všech buňkách
- Automatická šířka sloupců a výška řádků (
autofit) - Zmrazení prvního řádku (
freeze_panes = "A2") - 8 sloupců:
#|Lékař/Datum|Odbornost/Vydaný lék|Pracoviště/ATC| … |Předpisů/Pracoviště a adresa
Tabulka lékařů (8 sloupců)
# | Lékař | Odbornost | Pracoviště | Ulice | PSČ | Město | Předpisů
Tabulka předpisů (8 sloupců)
# | Datum | Vydaný lék | ATC | Návod | Lékař | Odbornost | Pracoviště a adresa
Závislosti
pymysql ← MySQL klient
fdb ← Firebird klient
openpyxl ← Excel export (pouze prehled_pacienta_excel.py)
Všechny jsou součástí requirements.txt a nainstalují se přes setup.ps1.
Typické chybové situace
| Chyba | Příčina | Řešení |
|---|---|---|
Rodne cislo nenalezeno v Medicusu |
RC není v tabulce KAR | Zkontrolovat číslo, ověřit v Medicusu |
Pacient nema zaznam v MySQL |
Lékový záznam nebyl stažen | Spustit 07StahnoutVsechny.py nebo reimport_z_xml.py |
PermissionError při ukládání xlsx |
Soubor je otevřen v Excelu | Zavřít Excel a spustit znovu — verzování uloží jako _v2 |
Odbornost zobrazena jako odb. XXX |
Kód není ve slovníku | Informativní stav — kód je platný, jen není pojmenován |