Nenhuma descrição
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

merge_province.py 7.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """
  4. Script per il merge dei file provincia.sql di IT e CH
  5. - Mantiene gli ID originali per IT
  6. - Rinumera gli ID per CH (da 112 in poi)
  7. - Aggiorna i provincia_id nei comuni CH
  8. """
  9. import re
  10. import os
  11. def parse_provincia_sql(file_path):
  12. """Parsa un file SQL provincia e estrae le righe INSERT"""
  13. with open(file_path, 'r', encoding='utf-8') as f:
  14. content = f.read()
  15. # Trova la sezione VALUES
  16. values_match = re.search(r'VALUES\s*(.*?);', content, re.DOTALL | re.IGNORECASE)
  17. if not values_match:
  18. print(f"Errore: non trovo la sezione VALUES in {file_path}")
  19. return []
  20. values_section = values_match.group(1)
  21. # Estrae le righe individuali
  22. rows = []
  23. # Pattern migliorato per matchare le righe con apostrofi escaped: (id, nome, sigla, ...)
  24. # Gestisce sia apostrofi normali che escaped (\')
  25. pattern = r'\((\d+),\s*\'((?:[^\'\\]|\\.)*)\',\s*\'([^\']*)\''
  26. matches = re.findall(pattern, values_section)
  27. for match in matches:
  28. id_val, nome, sigla = match
  29. # Decodifica gli apostrofi escaped
  30. nome = nome.replace("\\'", "'")
  31. rows.append({
  32. 'id': int(id_val),
  33. 'nome': nome,
  34. 'sigla': sigla
  35. })
  36. return rows
  37. def parse_comune_sql(file_path):
  38. """Parsa un file SQL comune e estrae le righe INSERT"""
  39. with open(file_path, 'r', encoding='utf-8') as f:
  40. content = f.read()
  41. # Trova la sezione VALUES
  42. values_match = re.search(r'VALUES\s*(.*?);', content, re.DOTALL | re.IGNORECASE)
  43. if not values_match:
  44. print(f"Errore: non trovo la sezione VALUES in {file_path}")
  45. return []
  46. values_section = values_match.group(1)
  47. # Estrae le righe individuali
  48. rows = []
  49. # Pattern per matchare le righe: (id, provincia_id, nome, codice_catastale, ...)
  50. pattern = r'\((\d+),\s*(\d+),\s*\'([^\']*)\',\s*\'?([^\',]*)\'?'
  51. matches = re.findall(pattern, values_section)
  52. for match in matches:
  53. id_val, provincia_id, nome, codice_catastale = match
  54. rows.append({
  55. 'id': int(id_val),
  56. 'provincia_id': int(provincia_id),
  57. 'nome': nome,
  58. 'codice_catastale': codice_catastale if codice_catastale != 'NULL' else None
  59. })
  60. return rows
  61. def generate_provincia_merged_sql(it_province, ch_province, output_file):
  62. """Genera il file SQL di merge per le province"""
  63. # Trova l'ID massimo delle province IT
  64. max_it_id = max(provincia['id'] for provincia in it_province)
  65. print(f"ID massimo province IT: {max_it_id}")
  66. # Crea mappa per la rinumerazione CH
  67. ch_id_mapping = {}
  68. new_ch_id = max_it_id + 1 # Inizia da max_it_id + 1
  69. for provincia in ch_province:
  70. ch_id_mapping[provincia['id']] = new_ch_id
  71. new_ch_id += 1
  72. with open(output_file, 'w', encoding='utf-8') as f:
  73. f.write("INSERT INTO `provincia` (\n")
  74. f.write(" `id`,\n")
  75. f.write(" `nome`,\n")
  76. f.write(" `sigla`,\n")
  77. f.write(" `created_at`,\n")
  78. f.write(" `updated_at`,\n")
  79. f.write(" `nazione_id`\n")
  80. f.write(") VALUES\n")
  81. all_rows = []
  82. # Processa province IT (mantengono ID originali, nazione_id = 118)
  83. for provincia in it_province:
  84. # Escape degli apostrofi nel nome per SQL
  85. nome_escaped = provincia['nome'].replace("'", "\\'")
  86. all_rows.append(
  87. f"({provincia['id']}, '{nome_escaped}', '{provincia['sigla']}', NULL, NULL, 118)"
  88. )
  89. # Processa province CH (rinumerate, nazione_id = 220)
  90. for provincia in ch_province:
  91. new_id = ch_id_mapping[provincia['id']]
  92. # Escape degli apostrofi nel nome per SQL
  93. nome_escaped = provincia['nome'].replace("'", "\\'")
  94. all_rows.append(
  95. f"({new_id}, '{nome_escaped}', '{provincia['sigla']}', NULL, NULL, 220)"
  96. )
  97. # Scrivi tutte le righe
  98. f.write(",\n".join(all_rows))
  99. f.write(";\n")
  100. # Aggiungi statistiche
  101. f.write(f"\n-- Statistiche merge province:\n")
  102. f.write(f"-- Province IT: {len(it_province)} (ID 1-{max_it_id})\n")
  103. f.write(f"-- Province CH: {len(ch_province)}\n")
  104. f.write(f"-- Totale province: {len(all_rows)}\n")
  105. f.write(f"-- Mappa rinumerazione CH:\n")
  106. for old_id, new_id in ch_id_mapping.items():
  107. f.write(f"-- {old_id} -> {new_id}\n")
  108. return ch_id_mapping
  109. def update_comune_merged_sql(ch_id_mapping, comune_merged_file):
  110. """Aggiorna i provincia_id nei comuni CH del file comune_merged.sql"""
  111. # Leggi il file esistente
  112. with open(comune_merged_file, 'r', encoding='utf-8') as f:
  113. content = f.read()
  114. # Trova la sezione VALUES
  115. values_match = re.search(r'VALUES\s*(.*?);', content, re.DOTALL | re.IGNORECASE)
  116. if not values_match:
  117. print("Errore: non trovo la sezione VALUES nel file comune_merged.sql")
  118. return
  119. values_section = values_match.group(1)
  120. # Pattern per matchare le righe dei comuni CH (nazione_id = 220)
  121. # Gli ID dei comuni CH ora partono da 110015
  122. pattern = r'\((\d+),\s*(\d+),\s*\'([^\']*)\',\s*\'?([^\',]*)\'?,\s*NULL,\s*NULL,\s*220\)'
  123. def replace_ch_comune(match):
  124. id_val, provincia_id, nome, codice_catastale = match.groups()
  125. comune_id = int(id_val)
  126. old_provincia_id = int(provincia_id)
  127. # Se è un comune CH (ID >= 110015 e nazione_id = 220), aggiorna il provincia_id
  128. if comune_id >= 110015 and old_provincia_id in ch_id_mapping:
  129. new_provincia_id = ch_id_mapping[old_provincia_id]
  130. codice = f"'{codice_catastale}'" if codice_catastale != 'NULL' else 'NULL'
  131. return f"({comune_id}, {new_provincia_id}, '{nome}', {codice}, NULL, NULL, 220)"
  132. return match.group(0) # Mantieni invariato se non è un comune CH
  133. # Sostituisci i provincia_id per i comuni CH
  134. updated_values = re.sub(pattern, replace_ch_comune, values_section)
  135. # Ricostruisci il file
  136. new_content = content.replace(values_section, updated_values)
  137. # Scrivi il file aggiornato
  138. with open(comune_merged_file, 'w', encoding='utf-8') as f:
  139. f.write(new_content)
  140. print(f"Aggiornati i provincia_id per {len(ch_id_mapping)} province CH nel file comune_merged.sql")
  141. def main():
  142. # Percorsi dei file
  143. base_dir = os.path.dirname(os.path.abspath(__file__))
  144. it_provincia_file = os.path.join(base_dir, 'it', 'provincia.sql')
  145. ch_provincia_file = os.path.join(base_dir, 'ch', 'provincia.sql')
  146. provincia_merged_file = os.path.join(base_dir, 'provincia_merged.sql')
  147. comune_merged_file = os.path.join(base_dir, 'comune_merged.sql')
  148. print("Inizio parsing province IT...")
  149. it_province = parse_provincia_sql(it_provincia_file)
  150. print(f"Trovate {len(it_province)} province nel file IT")
  151. print("Inizio parsing province CH...")
  152. ch_province = parse_provincia_sql(ch_provincia_file)
  153. print(f"Trovate {len(ch_province)} province nel file CH")
  154. print("Generazione file di merge province...")
  155. ch_id_mapping = generate_provincia_merged_sql(it_province, ch_province, provincia_merged_file)
  156. print(f"File provincia_merged.sql generato: {provincia_merged_file}")
  157. print(f"Totale province nel file finale: {len(it_province) + len(ch_province)}")
  158. print("Aggiornamento provincia_id nei comuni CH...")
  159. update_comune_merged_sql(ch_id_mapping, comune_merged_file)
  160. print("Merge completato!")
  161. if __name__ == "__main__":
  162. main()