Files
recept/LékovýZáznamWithClaude/LEKOVY_ZAZNAM_DB.md
T
2026-04-06 21:37:25 +02:00

10 KiB
Raw Blame History

Lékový záznam eRecept → MySQL

Popis pipeline pro stažení lékového záznamu pacienta z eRecept SÚKL API a jeho uložení do relační databáze MySQL.


Soubory

Soubor Co dělá
05UlozitOdpoved.py Zavolá SOAP API, stáhne XML odpověď, uloží ji do odpoved_lekovy_zaznam.xml
06UlozitDoMySQL.py Naparsuje uložené XML, vytvoří/přepíše tabulky v MySQL, vloží data

Typické spuštění

# 1. stáhnout čerstvá data z eReceptu
python 05UlozitOdpoved.py

# 2. uložit do databáze
python 06UlozitDoMySQL.py

# nebo předat jiný XML soubor
python 06UlozitDoMySQL.py C:\cesta\k\jine_odpovedi.xml

Autentizace (eRecept SÚKL, ostrý provoz)

Parametr Hodnota
Endpoint https://lekar-soap.erecept.sukl.cz/cuer/Lekar2
mTLS certifikát AMBSUKL214235369G_31DEC2024.pfx (platnost do 31. 12. 2026)
HTTP Basic user UUID lékaře e08c89c6-2b1a-4eba-8ed9-4e3e63618379
SOAP operace NacistLekovyZaznam
XML namespace http://www.sukl.cz/erp/201912
Verze zprávy 202501A

Certifikát = identifikace ordinace, UUID+heslo = identifikace lékaře jako osoby.


Dotaz — parametry NacistLekovyZaznamLekarDotaz

<Doklad>
  <Pristupujici>
    <Uzivatel>UUID lékaře</Uzivatel>
    <Pracoviste>IČP ordinace</Pracoviste>
  </Pristupujici>
  <PocetZnakuATC>7</PocetZnakuATC>   <!-- 5 nebo 7 -->
  <PocetMesicu>60</PocetMesicu>       <!-- max 99 -->
  <Pacient>
    <Totoznost>
      <Jmeno><Prijmeni>...</Prijmeni><Jmena>...</Jmena></Jmeno>
      <DatumNarozeni>YYYY-MM-DD</DatumNarozeni>
    </Totoznost>
  </Pacient>
</Doklad>

Struktura XML odpovědi

Dle XSD Cuer2Schema.xsd + CuerSchema.xsd, verze 202501A:

NacistLekovyZaznamOdpoved
├── Doklad
│   ├── Pacient                     jméno + datum narození
│   ├── PredepisujiciSeznam         lékaři, kteří předepisovali
│   ├── VydavajiciSeznam            lékárny, kde byl výdej
│   ├── PredpisSeznam
│   │   └── Predpis × N            co bylo předepsáno
│   ├── VydejSeznam
│   │   └── Vydej × N              co bylo vydáno v lékárně
│   └── DuplicitaSeznam             duplicitní výdeje
└── Zprava                          metadata odpovědi (ID, čas, verze SW)

Typy léků v Predpis i Vydej

Každý předpis / výdej obsahuje právě jeden z těchto elementů:

Typ Popis Klíčová pole
HVLPReg Registrovaný hromadně vyráběný LP Kod (SÚKL), ATC, Nazev, Forma, Sila, Baleni
HVLPNereg Neregistrovaný HVLP stejná struktura jako HVLPReg
IPLP Individuálně připravovaný LP (magistraliter) Nazev, PostupPripravy (receptura), Slozka[]
INN Předpis účinnou látkou (genericky) Nazev, Forma, Sila, Baleni

IPLP — dvojí uložení receptury

  • Předpis (PredpisSeznam/Predpis/IPLP): lékař zadal recepturu jako volný text v PostupPripravy. Prvky Slozka zde lékař typicky nevyplňuje.
  • Výdej (VydejSeznam/Vydej/IPLP): lékárna při přípravě zaznamenala strukturované složky (Slozka s množstvím, jednotkou a názvem suroviny). Kvalita dat závisí na lékárně — některé rozkládají do detailu (suroviny, obal, taxa laborum), jiné evidují jen 1 ks jako celek.

Databázové schéma — medicus (MySQL 9.6)

Všechny délky a datové typy jsou přesně dle XSD, ne odhady. Varianta B — lék je denormalizován přímo do řádku předpisu/výdeje.

Relační diagram

zprava (1)
  ├── predpis (N)
  │     └── predpis_slozka (N)   -- složky IPLP z předpisu
  └── vydej (N)
        └── vydej_slozka (N)     -- složky IPLP z výdeje

vydej.id_lp_predpis → predpis.id_lp_predpis   (párování výdeje s předpisem)

Tabulka zprava

Jeden řádek = jedna odpověď API (jedno volání NacistLekovyZaznam).

Sloupec Typ Zdroj v XSD
id_zpravy CHAR(36) UNIQUE zprava_type.ID_Zpravy
verze VARCHAR(20) zprava_type.Verze
odeslano DATETIME zprava_type.Odeslano
aplikace VARCHAR(512) zprava_odpoved_type.Aplikace
id_podani CHAR(36) zprava_odpoved_type.ID_Podani
prijato DATETIME zprava_odpoved_type.Prijato
pacient_prijmeni VARCHAR(35) jmeno_osoby_type.Prijmeni
pacient_jmena VARCHAR(24) jmeno_osoby_type.Jmena
pacient_datum_narozeni DATE lz_totoznost_type.DatumNarozeni
stazeno DATETIME automaticky při INSERT

Tabulka predpis

Dle lz_nacteni_predepsany_lp_erp_type.

Sloupec Typ NOT NULL Poznámka
id_lp_predpis CHAR(36) UUID z eReceptu, globálně unikátní
kod_predepisujiciho VARCHAR(36) UUID lékaře
datum_vystaveni DATE
mnozstvi SMALLINT 19999
navod VARCHAR(80) max 80 znaků dle XSD
opakovani INT opakování předpisu
modry_pruh TINYINT(1) modrý pruh (návykové látky)
typ_leku ENUM HVLPReg / HVLPNereg / IPLP / INN
lek_kod CHAR(7) kód SÚKL (jen HVLP)
atc VARCHAR(7) ATC kód (jen HVLP)
nazev VARCHAR(200) max 200 — INN má nejdelší název
forma VARCHAR(27) léková forma
sila VARCHAR(24) síla přípravku
cesta_podani VARCHAR(15) POR, INH, …
baleni VARCHAR(22) string, ne číslo (může být "100 ks")
postup_pripravy VARCHAR(4000) receptura IPLP jako volný text

Tabulka predpis_slozka

Dle slozka_iplp_predpis_type. Řádky vznikají jen pro IPLP předpisy se strukturovanými složkami.

Sloupec Typ NOT NULL Poznámka
predpis_id INT FK → predpis.id
mnozstvi DECIMAL(15,6) přesné množství suroviny
jednotka ENUM('g','ks')
nazev VARCHAR(200) název suroviny / přípravku
surovina CHAR(7) kód suroviny v registru SÚKL
hvlp_reg CHAR(7) pokud je složka registrovaný HVLP

Tabulka vydej

Dle lz_nacteni_vydany_lp_erp_type.

Sloupec Typ NOT NULL Poznámka
id_lp_vydej CHAR(36) UUID výdeje
id_lp_predpis CHAR(36) FK → predpis.id_lp_predpis, NULL = výdej bez e-předpisu
kod_vydavajiciho VARCHAR(36) UUID lékárníka
datum_vydeje DATE
mnozstvi DECIMAL(6,2) desetinné — např. 0.5 balení
navod VARCHAR(80)
exspirace DATE exspirace šarže
sarze VARCHAR(50) číslo šarže
seriove_cislo VARCHAR(20) sériové číslo (léky s el. sledováním)
pozn VARCHAR(1000) poznámka lékárníka
typ_leku ENUM HVLPReg / HVLPNereg / IPLP
lek_kod CHAR(7) kód SÚKL (HVLP) nebo KodVZP (IPLP)
atc VARCHAR(7) jen HVLP
nazev VARCHAR(146)
forma VARCHAR(27)
sila VARCHAR(24)
cesta_podani VARCHAR(15)
postup_pripravy VARCHAR(4000) receptura IPLP

Tabulka vydej_slozka

Dle slozka_iplp_type. Jako predpis_slozka, ale navíc obsahuje hrazeno_zp.

Sloupec Typ NOT NULL Poznámka
vydej_id INT FK → vydej.id
mnozstvi DECIMAL(15,6)
jednotka ENUM('g','ks')
nazev VARCHAR(200) název suroviny
hrazeno_zp DECIMAL(9,2) částka hrazená zdravotní pojišťovnou
surovina CHAR(7)
hvlp_reg CHAR(7)

Klíčové vlastnosti importu (06UlozitDoMySQL.py)

  • Idempotentní: INSERT IGNORE na id_lp_predpis / id_lp_vydej — opakované spuštění se stejným XML nepřidá duplikáty.
  • Víc pacientů: zprava.id_zpravy je UNIQUE — každé volání API (jiný pacient, jiný čas) vytvoří nový řádek v zprava. Předpisy a výdeje napříč pacienty se agregují v predpis / vydej.
  • Schema se přepisuje: vytvor_schema() vždy DROPne a znovu vytvoří všech 5 tabulek. Při produkčním použití (více pacientů) tuto část odstraňte a spouštějte DDL jen jednou při inicializaci.

Užitečné analytické dotazy

-- nejčastěji předepisované ATC skupiny za posledních 12 měsíců
SELECT atc, nazev, COUNT(*) AS pocet, MAX(datum_vystaveni) AS naposledy
FROM predpis
WHERE datum_vystaveni >= DATE_SUB(CURDATE(), INTERVAL 12 MONTH)
GROUP BY atc, nazev
ORDER BY pocet DESC;

-- co bylo předepsáno ale nevyzvednuto
SELECT p.datum_vystaveni, p.nazev, p.atc, p.navod
FROM predpis p
LEFT JOIN vydej v ON v.id_lp_predpis = p.id_lp_predpis
WHERE v.id_lp_vydej IS NULL;

-- IPLP magistraliter — kompletní receptury s frekvencí
SELECT p.nazev, p.postup_pripravy,
       COUNT(*) AS pocet_predpisu
FROM predpis p
WHERE p.typ_leku = 'IPLP'
GROUP BY p.nazev, p.postup_pripravy
ORDER BY pocet_predpisu DESC;

-- IPLP výdeje — strukturované složky (kde je lékárna zadala)
SELECT v.datum_vydeje, v.nazev AS pripravek,
       GROUP_CONCAT(s.mnozstvi, ' ', s.jednotka, ' ', s.nazev
                    ORDER BY s.id SEPARATOR ' + ') AS slozeni
FROM vydej v
JOIN vydej_slozka s ON s.vydej_id = v.id
WHERE v.typ_leku = 'IPLP'
GROUP BY v.id
ORDER BY v.datum_vydeje DESC;

-- nejčastěji používané suroviny v magistrech (ze strany výdeje)
SELECT nazev, jednotka, COUNT(*) AS pocet
FROM vydej_slozka
GROUP BY nazev, jednotka
ORDER BY pocet DESC;

-- párování: co předepsal lékař vs. co lékárna vydala (generická záměna)
SELECT p.datum_vystaveni,
       p.nazev AS predepsano, p.atc,
       v.nazev AS vydano,     v.datum_vydeje
FROM predpis p
JOIN vydej v ON v.id_lp_predpis = p.id_lp_predpis
WHERE p.nazev <> v.nazev;

Závislosti (Python)

requests
requests-pkcs12
pymysql
pip install requests requests-pkcs12 pymysql

XSD zdroje

Schéma verze 202501A, soubory v Dokumentace/2025-04-24/WSDL_XSD/NEPRIORITNI_WEBOVE_SLUZBY/:

Soubor Obsah
Cuer2Schema.xsd Typy specifické pro lékový záznam: NacistLekovyZaznamOdpoved, lz_nacteni_predepsany_lp_erp_type, lz_nacteni_vydany_lp_erp_type, slozka_iplp_*
CuerSchema.xsd Společné typy: hvlp_type, zprava_odpoved_type, zprava_type, jmeno_osoby_type, jednotka