""" Reimport vsech XML souboru z xml_archive do MySQL — bez volani API. Pouziti: python reimport_z_xml.py # vsechna XML z 2026-04-11 python reimport_z_xml.py xml_archive/2026-04-11 # konkretni adresar python reimport_z_xml.py xml_archive # vsechny podadresare rekurzivne """ import sys import importlib.util from pathlib import Path from datetime import date import fdb import pymysql import pymysql.cursors # Windows konzole if hasattr(sys.stdout, "reconfigure"): sys.stdout.reconfigure(errors="replace") # ── Konfigurace ─────────────────────────────────────────────────────────────── XML_ADRESAR = Path(__file__).parent / "xml_archive" / "2026-04-11" FB = dict( dsn = r"localhost:c:\medicus 3\data\medicus.fdb", user = "SYSDBA", password = "masterkey", charset = "win1250", ) DB = dict( host = "192.168.1.76", user = "root", password = "Vlado9674+", database = "medicus", charset = "utf8mb4", cursorclass = pymysql.cursors.DictCursor, ) ICP = "09305001" ODB = "001" # ───────────────────────────────────────────────────────────────────────────── # Nacteni parsovaci logiky z 06UlozitDoMySQL.py _spec = importlib.util.spec_from_file_location( "m06", Path(__file__).parent / "06UlozitDoMySQL.py" ) _m06 = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_m06) parsuj_xml = _m06.parsuj_xml uloz = _m06.uloz inicializuj_schema = _m06.inicializuj_schema def nacti_pacienty_z_fb(): """Vrati slovnik {(prijmeni_upper, datnar): idpac} ze vsech pacientu v Medicusu.""" conn = fdb.connect(**FB) try: cur = conn.cursor() dnes = date.today().isoformat() cur.execute(""" SELECT KAR.IDPAC, KAR.PRIJMENI, KAR.JMENO, KAR.DATNAR FROM KAR WHERE KAR.vyrazen = 'N' AND EXISTS ( SELECT 1 FROM registr r JOIN icp i ON r.idicp = i.idicp WHERE r.idpac = kar.idpac AND r.datum <= ? AND (r.datum_zruseni IS NULL OR r.datum_zruseni >= ?) AND r.priznak IN ('V','D','A') AND i.icp = ? AND i.odb = ? ) """, (dnes, dnes, ICP, ODB)) result = {} for row in cur.fetchall(): idpac, prijmeni, jmeno, datnar = row klic = (prijmeni.strip().upper(), datnar) result[klic] = {"idpac": idpac, "prijmeni": prijmeni.strip(), "jmeno": jmeno.strip(), "datnar": datnar} print(f"Firebird: nacteno {len(result)} registrovanych pacientu") return result finally: conn.close() def upsert_pacient(cur, pac): cur.execute(""" INSERT INTO pacient (idpac, prijmeni, jmena, datum_narozeni) VALUES (%s, %s, %s, %s) ON DUPLICATE KEY UPDATE prijmeni = VALUES(prijmeni), jmena = VALUES(jmena) """, (pac["idpac"], pac["prijmeni"], pac["jmeno"], pac["datnar"])) cur.execute("SELECT id FROM pacient WHERE idpac = %s", (pac["idpac"],)) return cur.fetchone()["id"] def main(): # Adresar z argumentu nebo default adresar = Path(sys.argv[1]) if len(sys.argv) > 1 else XML_ADRESAR if not adresar.is_dir(): sys.exit(f"Adresar neexistuje: {adresar}") # Najdi vsechna XML rekurzivne xml_soubory = sorted(adresar.rglob("*.xml")) if not xml_soubory: sys.exit(f"Zadne XML soubory nalezeny v: {adresar}") print(f"Nalezeno {len(xml_soubory)} XML souboru v: {adresar}") # Nacti pacienty z Firebirdu fb_pacienti = nacti_pacienty_z_fb() # Pripoj se k MySQL a inicializuj schema conn = pymysql.connect(**DB) try: inicializuj_schema(conn) ok = chyba = preskoceno = 0 p_celkem = v_celkem = 0 for i, xml_path in enumerate(xml_soubory, 1): rel = xml_path.relative_to(Path(__file__).parent) try: zprava, predpisy, vydeji, predepisujici, vydavajici = parsuj_xml(xml_path) except Exception as e: print(f"[{i:4}/{len(xml_soubory)}] {xml_path.name:<45} CHYBA parsovani: {e}") chyba += 1 continue # Zjisti prijmeni a datum narozeni z XML odpovedi pac_prijmeni = (zprava.get("pacient_prijmeni") or "").upper() pac_datnar = zprava.get("pacient_datum_narozeni") # string YYYY-MM-DD nebo None # Prevod na date objekt pro porovnani s Firebirdem if pac_datnar and isinstance(pac_datnar, str): try: from datetime import datetime pac_datnar_d = datetime.strptime(pac_datnar[:10], "%Y-%m-%d").date() except ValueError: pac_datnar_d = None elif hasattr(pac_datnar, "year"): pac_datnar_d = pac_datnar else: pac_datnar_d = None klic = (pac_prijmeni, pac_datnar_d) fb_pac = fb_pacienti.get(klic) if not fb_pac: # Pacient neni registrovan — uloz bez idpac (bude ignorovan pri hromadnem behu) # Zkus najit v MySQL podle jmena a data with conn.cursor() as cur: cur.execute( "SELECT id FROM pacient WHERE prijmeni = %s AND datum_narozeni = %s", (zprava.get("pacient_prijmeni"), pac_datnar) ) row = cur.fetchone() if row: pacient_id = row["id"] else: preskoceno += 1 print(f"[{i:4}/{len(xml_soubory)}] {xml_path.name:<45} PRESKOCENO (neni v registru)") continue else: with conn.cursor() as cur: pacient_id = upsert_pacient(cur, fb_pac) conn.commit() try: stats = uloz(conn, zprava, predpisy, vydeji, predepisujici, vydavajici, pacient_id=pacient_id, xml_soubor=str(rel)) conn.commit() p_celkem += stats["predpisy_novych"] v_celkem += stats["vydeji_novych"] print(f"[{i:4}/{len(xml_soubory)}] {xml_path.name:<45} OK " f"{stats['predpisy_novych']:3}p {stats['vydeji_novych']:3}v") ok += 1 except Exception as e: conn.rollback() print(f"[{i:4}/{len(xml_soubory)}] {xml_path.name:<45} CHYBA ukladani: {e}") chyba += 1 print() print(f"Hotovo: {ok} OK, {chyba} chyb, {preskoceno} preskoceno") print(f"Celkem vlozeno: {p_celkem} predpisu, {v_celkem} vydejuu") finally: conn.close() if __name__ == "__main__": main()