qgis_sync_etancheite.py 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. """
  2. Met à jour les résultats des contrôles d'étanchéité des regards et tronçons de la base POSTGIS
  3. Les résultats à jour sont issus de la base Contrôles
  4. Pour des raisons de performances, seuls sont contrôlés les essais datant de moins de X mois,
  5. où X vaut 24 par défaut
  6. Pour être analysés, les noms des tronçons de la base Contrôles doivent être de la forme
  7. 'R1-R2' ou 'R2-R1' (les espaces sont acceptés avant et aprés le tiret séparateur)
  8. @author: olivier.massot, mai 2018
  9. """
  10. from datetime import datetime
  11. import logging
  12. import re
  13. from dateutil.relativedelta import relativedelta
  14. from path import Path
  15. from core import logconf
  16. from core.model import Sql
  17. from core.pde import ControlesDb, WincanDb, CSigDb
  18. logger = logging.getLogger("qgis_sync_etancheite")
  19. logconf.start("qgis_sync_etancheite", logging.DEBUG)
  20. IMPORT_DEPUIS = 24 # Ne cherche des données à importer que sur les X derniers mois (mettre à 0 pour ignorer)
  21. # # POUR TESTER, décommenter les lignes suivantes
  22. ##-----------------------------------------------
  23. # ControlesDb._path = Path(r"\\h2o\local\4-transversal\BDD\mdb_test\cg67Parc_data.mdb")
  24. # CSigDb.server = "TR-POSTGIS-02"
  25. # CSigDb.pwd = "Am5VOMkdFHU7WwrfVOs9"
  26. # logger.handlers = [h for h in logger.handlers if (type(h) == logging.StreamHandler)]
  27. # logger.warning("<<<<<<<<<<<<<< Mode TEST >>>>>>>>>>>>>>>>>")
  28. ##-----------------------------------------------
  29. # Connexion à ControlesSig (postgres)
  30. csig_db = CSigDb(autocommit=False)
  31. # Connexion à Controles
  32. controles_db = ControlesDb(autocommit=False)
  33. # Connexion à Wincan
  34. wincan_db = WincanDb(autocommit=False)
  35. # filter results on the last X months, depending on corresponding parameter
  36. date_min = datetime.today() - relativedelta(months=IMPORT_DEPUIS) if IMPORT_DEPUIS >= 0 else datetime(1899, 12, 30, 0, 0, 0)
  37. logger.info("Loading data")
  38. # NB: utiliser une erquête access pré-enregistrée permet d'améliorer les perfs (la requete est pré-compilée)
  39. qessais = controles_db.read(Sql.format("""SELECT tblEtancheiteResultats.lngChantierId, tblEtancheitePartChantiers.strTrcRegard, tblTypeEssais.strObjetEssai, tblEtancheiteResultats.strResSigne, tblEtancheiteResultats.dtmEssai
  40. FROM ((tblTypeEssais INNER JOIN tblEtancheitePartChantiers ON tblTypeEssais.bytTypeEssaiId = tblEtancheitePartChantiers.bytTypeEssai) INNER JOIN
  41. tblEtancheiteResultats ON (tblEtancheitePartChantiers.bytPartChantierId = tblEtancheiteResultats.bytPartChantierId) AND
  42. (tblEtancheitePartChantiers.lngChantierId = tblEtancheiteResultats.lngChantierId)) INNER JOIN (SELECT tblEtancheiteResultats.lngChantierId, Max(tblEtancheiteResultats.bytIntervId) AS MaxDebytIntervId, tblEtancheiteResultats.bytPartChantierId
  43. FROM tblEtancheiteResultats
  44. GROUP BY tblEtancheiteResultats.lngChantierId, tblEtancheiteResultats.bytPartChantierId) as filter_intervs ON
  45. (tblEtancheiteResultats.bytPartChantierId = filter_intervs.bytPartChantierId) AND
  46. (tblEtancheiteResultats.bytIntervId = filter_intervs.MaxDebytIntervId) AND
  47. (tblEtancheiteResultats.lngChantierId = filter_intervs.lngChantierId)
  48. WHERE tblEtancheiteResultats.dtmEssai>{:date};
  49. """, date_min))
  50. nb_r, nb_t = 0, 0
  51. for essai in qessais:
  52. # L'essai concerne un regard
  53. if essai.strObjetEssai == "R":
  54. # # Cherche le regard correspondant dans qregards
  55. regard = csig_db.first(Sql.format("""SELECT t_regards.id, t_regards.res_ce
  56. FROM t_regards INNER JOIN t_chantiers ON t_regards.id_chantier = t_chantiers.id
  57. WHERE t_regards.nom={:text} AND t_chantiers.numero={} AND t_regards.archive=False
  58. """, essai.strTrcRegard, essai.lngChantierId))
  59. if not regard:
  60. continue
  61. if regard.res_ce != essai.strResSigne:
  62. q = csig_db.execute(Sql.format("""UPDATE t_regards
  63. SET res_ce = {res_ce:text}
  64. WHERE id = {pgid}
  65. """, res_ce=essai.strResSigne, pgid=regard.id))
  66. nb_r += 1
  67. logger.info("Résultat mis à jour: %s, %s > %s", essai.lngChantierId, essai.strTrcRegard, essai.strResSigne)
  68. # L'essai concerne un tronçon
  69. elif essai.strObjetEssai == "T":
  70. # Parse le nom de tronçon
  71. regex = re.search(r"^(\S*)\s?-\s?(\S*)$", essai.strTrcRegard)
  72. if not regex:
  73. logger.error(u"Nom de tronçon invalide: '{}' (chantier: {})".format(essai.strTrcRegard, essai.lngChantierId))
  74. continue
  75. r1, r2 = regex.group(1), regex.group(2)
  76. troncon = csig_db.first(Sql.format("""SELECT t_troncons.id, t_chantiers.numero, t_regards_1.nom AS r1,
  77. t_regards.nom AS r2, t_troncons.res_ce, t_troncons.nom as nom
  78. FROM ((t_troncons INNER JOIN t_chantiers ON t_troncons.id_chantier = t_chantiers.id)
  79. INNER JOIN t_regards AS t_regards_1 ON t_troncons.id_regard_depart = t_regards_1.id)
  80. INNER JOIN t_regards ON t_troncons.id_regard_fin = t_regards.id
  81. WHERE ((t_regards_1.nom={r1:text} AND t_regards.nom={r2:text})
  82. OR (t_regards_1.nom={r2:text} AND t_regards.nom={r1:text}))
  83. AND t_chantiers.numero={num_chantier} AND t_troncons.archive=False
  84. """, r1=r1, r2=r2, num_chantier=essai.lngChantierId))
  85. if not troncon:
  86. continue
  87. if troncon.res_ce != essai.strResSigne:
  88. q = csig_db.execute(Sql.format("""UPDATE t_troncons
  89. SET res_ce = {res_ce:text}
  90. WHERE id = {pgid};""", res_ce=essai.strResSigne, pgid=troncon.id))
  91. nb_t += 1
  92. logger.info("Résultat mis à jour: %s, %s > %s", essai.lngChantierId, essai.strTrcRegard, essai.strResSigne)
  93. csig_db.commit()
  94. logger.info("- Opération terminée -")
  95. logger.info("%s regards et %s tronçons mis à jour", nb_r, nb_t)