#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Script per il merge dei file provincia.sql di IT e CH - Mantiene gli ID originali per IT - Rinumera gli ID per CH (da 112 in poi) - Aggiorna i provincia_id nei comuni CH """ import re import os def parse_provincia_sql(file_path): """Parsa un file SQL provincia e estrae le righe INSERT""" with open(file_path, 'r', encoding='utf-8') as f: content = f.read() # Trova la sezione VALUES values_match = re.search(r'VALUES\s*(.*?);', content, re.DOTALL | re.IGNORECASE) if not values_match: print(f"Errore: non trovo la sezione VALUES in {file_path}") return [] values_section = values_match.group(1) # Estrae le righe individuali rows = [] # Pattern migliorato per matchare le righe con apostrofi escaped: (id, nome, sigla, ...) # Gestisce sia apostrofi normali che escaped (\') pattern = r'\((\d+),\s*\'((?:[^\'\\]|\\.)*)\',\s*\'([^\']*)\'' matches = re.findall(pattern, values_section) for match in matches: id_val, nome, sigla = match # Decodifica gli apostrofi escaped nome = nome.replace("\\'", "'") rows.append({ 'id': int(id_val), 'nome': nome, 'sigla': sigla }) return rows def parse_comune_sql(file_path): """Parsa un file SQL comune e estrae le righe INSERT""" with open(file_path, 'r', encoding='utf-8') as f: content = f.read() # Trova la sezione VALUES values_match = re.search(r'VALUES\s*(.*?);', content, re.DOTALL | re.IGNORECASE) if not values_match: print(f"Errore: non trovo la sezione VALUES in {file_path}") return [] values_section = values_match.group(1) # Estrae le righe individuali rows = [] # Pattern per matchare le righe: (id, provincia_id, nome, codice_catastale, ...) pattern = r'\((\d+),\s*(\d+),\s*\'([^\']*)\',\s*\'?([^\',]*)\'?' matches = re.findall(pattern, values_section) for match in matches: id_val, provincia_id, nome, codice_catastale = match rows.append({ 'id': int(id_val), 'provincia_id': int(provincia_id), 'nome': nome, 'codice_catastale': codice_catastale if codice_catastale != 'NULL' else None }) return rows def generate_provincia_merged_sql(it_province, ch_province, output_file): """Genera il file SQL di merge per le province""" # Trova l'ID massimo delle province IT max_it_id = max(provincia['id'] for provincia in it_province) print(f"ID massimo province IT: {max_it_id}") # Crea mappa per la rinumerazione CH ch_id_mapping = {} new_ch_id = max_it_id + 1 # Inizia da max_it_id + 1 for provincia in ch_province: ch_id_mapping[provincia['id']] = new_ch_id new_ch_id += 1 with open(output_file, 'w', encoding='utf-8') as f: f.write("INSERT INTO `provincia` (\n") f.write(" `id`,\n") f.write(" `nome`,\n") f.write(" `sigla`,\n") f.write(" `created_at`,\n") f.write(" `updated_at`,\n") f.write(" `nazione_id`\n") f.write(") VALUES\n") all_rows = [] # Processa province IT (mantengono ID originali, nazione_id = 118) for provincia in it_province: # Escape degli apostrofi nel nome per SQL nome_escaped = provincia['nome'].replace("'", "\\'") all_rows.append( f"({provincia['id']}, '{nome_escaped}', '{provincia['sigla']}', NULL, NULL, 118)" ) # Processa province CH (rinumerate, nazione_id = 220) for provincia in ch_province: new_id = ch_id_mapping[provincia['id']] # Escape degli apostrofi nel nome per SQL nome_escaped = provincia['nome'].replace("'", "\\'") all_rows.append( f"({new_id}, '{nome_escaped}', '{provincia['sigla']}', NULL, NULL, 220)" ) # Scrivi tutte le righe f.write(",\n".join(all_rows)) f.write(";\n") # Aggiungi statistiche f.write(f"\n-- Statistiche merge province:\n") f.write(f"-- Province IT: {len(it_province)} (ID 1-{max_it_id})\n") f.write(f"-- Province CH: {len(ch_province)}\n") f.write(f"-- Totale province: {len(all_rows)}\n") f.write(f"-- Mappa rinumerazione CH:\n") for old_id, new_id in ch_id_mapping.items(): f.write(f"-- {old_id} -> {new_id}\n") return ch_id_mapping def update_comune_merged_sql(ch_id_mapping, comune_merged_file): """Aggiorna i provincia_id nei comuni CH del file comune_merged.sql""" # Leggi il file esistente with open(comune_merged_file, 'r', encoding='utf-8') as f: content = f.read() # Trova la sezione VALUES values_match = re.search(r'VALUES\s*(.*?);', content, re.DOTALL | re.IGNORECASE) if not values_match: print("Errore: non trovo la sezione VALUES nel file comune_merged.sql") return values_section = values_match.group(1) # Pattern per matchare le righe dei comuni CH (nazione_id = 220) # Gli ID dei comuni CH ora partono da 110015 pattern = r'\((\d+),\s*(\d+),\s*\'([^\']*)\',\s*\'?([^\',]*)\'?,\s*NULL,\s*NULL,\s*220\)' def replace_ch_comune(match): id_val, provincia_id, nome, codice_catastale = match.groups() comune_id = int(id_val) old_provincia_id = int(provincia_id) # Se è un comune CH (ID >= 110015 e nazione_id = 220), aggiorna il provincia_id if comune_id >= 110015 and old_provincia_id in ch_id_mapping: new_provincia_id = ch_id_mapping[old_provincia_id] codice = f"'{codice_catastale}'" if codice_catastale != 'NULL' else 'NULL' return f"({comune_id}, {new_provincia_id}, '{nome}', {codice}, NULL, NULL, 220)" return match.group(0) # Mantieni invariato se non è un comune CH # Sostituisci i provincia_id per i comuni CH updated_values = re.sub(pattern, replace_ch_comune, values_section) # Ricostruisci il file new_content = content.replace(values_section, updated_values) # Scrivi il file aggiornato with open(comune_merged_file, 'w', encoding='utf-8') as f: f.write(new_content) print(f"Aggiornati i provincia_id per {len(ch_id_mapping)} province CH nel file comune_merged.sql") def main(): # Percorsi dei file base_dir = os.path.dirname(os.path.abspath(__file__)) it_provincia_file = os.path.join(base_dir, 'it', 'provincia.sql') ch_provincia_file = os.path.join(base_dir, 'ch', 'provincia.sql') provincia_merged_file = os.path.join(base_dir, 'provincia_merged.sql') comune_merged_file = os.path.join(base_dir, 'comune_merged.sql') print("Inizio parsing province IT...") it_province = parse_provincia_sql(it_provincia_file) print(f"Trovate {len(it_province)} province nel file IT") print("Inizio parsing province CH...") ch_province = parse_provincia_sql(ch_provincia_file) print(f"Trovate {len(ch_province)} province nel file CH") print("Generazione file di merge province...") ch_id_mapping = generate_provincia_merged_sql(it_province, ch_province, provincia_merged_file) print(f"File provincia_merged.sql generato: {provincia_merged_file}") print(f"Totale province nel file finale: {len(it_province) + len(ch_province)}") print("Aggiornamento provincia_id nei comuni CH...") update_comune_merged_sql(ch_id_mapping, comune_merged_file) print("Merge completato!") if __name__ == "__main__": main()