# ImdbUpdate - Python Embedded Version Conversione Python del codice VBA per l'aggiornamento dei dati IMDb. Completamente **portabile** e **autocontenuto** grazie a Python Embedded. ## Caratteristiche ### Miglioramenti rispetto al VBA - **Portabilità completa**: Usa Python Embedded, eseguibile da qualsiasi posizione senza installazione Python di sistema - **Supporto dual-architecture**: Include sia Python 32-bit che 64-bit, rileva automaticamente il driver ODBC disponibile - **Autocontenuto**: Tutte le dipendenze incluse nella cartella del progetto - **SQLite per processing intermedio**: Più veloce e performante di MS Access - **Export finale in MS Access**: Mantiene compatibilità con sistemi esistenti - **Preservazione indici**: Template Access mantiene indici su TI, TO, REGISTA - **Performance ottimizzate**: Query SQL ottimizzate con indici e GROUP_CONCAT - **Logging dettagliato**: Tracciamento completo di tutte le operazioni - **Gestione errori robusta**: Error handling migliore del VBA - **Progress bars**: Feedback visivo durante download - **Modulare**: Codice ben organizzato e testabile ## Storia del Progetto Questo progetto nasce dalla conversione di una procedura VBA originale in Python, con l'obiettivo di migliorare performance, manutenibilità e scalabilità. ### Evoluzione Performance - **VBA Originale**: ~180 minuti (3 ore) per processo completo - **Python v1.0**: Conversione iniziale con blocchi durante processing - **Python v1.1** (corrente): ~70-80 minuti con ottimizzazioni implementate ### Ottimizzazioni Chiave Implementate 1. **Fix SQL Keywords (TO, CAST)**: Risolto problema parole riservate SQL con quote syntax appropriata per SQLite e Access 2. **Fix CSV Field Limit**: Aumentato limite da 131KB a 10MB per gestire cast molto lunghi 3. **Ottimizzazione Query**: Sostituzione subquery correlate (O(n²)) con UPDATE...FROM + indici (O(n log m)) - speedup 12-20x su fase processamento 4. **Abilitazione OTT**: Implementato import provider streaming (Netflix, Prime Video, ecc.) da database esterno 5. **Import GemmaLoader**: Abilitato export automatico per reparto Acquisti 6. **Preservazione Indici Access**: Cambio logica da DROP TABLE a DELETE FROM per preservare indici dal template 7. **Conversione a Python Embedded**: Eliminata dipendenza da Python di sistema, progetto completamente portabile 8. **Fix Column Order Mismatch Access**: Risolto errore ODBC "Tipi di dati non corrispondenti" causato da disallineamento ordine colonne tra SQLite (12 col con OTT_EMESSO) e Access template (11 col senza OTT_EMESSO). Implementato mapping esplicito con conversione NULL → valori default **Risultato**: Speedup complessivo 2.3x rispetto a VBA, con processo stabile, completamente automatizzato e portabile. ## Requisiti - **Python Embedded** (già incluso nelle cartelle `python32/` e `python64/`) - MS Access ODBC Driver 32-bit o 64-bit (rilevato automaticamente all'avvio) - Windows (per compatibilità Access) ## Installazione **Nessuna installazione richiesta!** Il progetto usa Python Embedded ed è completamente autocontenuto. 1. **Copia la cartella del progetto** sul PC di destinazione 2. **Verifica template Access**: La cartella `Empty/` deve contenere `db_split_IMDB.accdb` con struttura tabella IMDB e indici su campi TI, TO, REGISTA 3. **Pronto all'uso**: Esegui `RUN.bat` ### Dipendenze Incluse Tutte le dipendenze Python sono già installate in `python32/` e `python64/`: - **Python 64-bit**: requests 2.32.5, pyodbc 5.3.0, pandas 2.3.3, tqdm 4.67.1, numpy 2.4.1 - **Python 32-bit**: requests 2.32.5, pyodbc 5.3.0, pandas 2.0.3, tqdm 4.67.1, numpy 2.4.1 Lo script `RUN.bat` rileva automaticamente quale driver ODBC è installato (32-bit o 64-bit) e usa la versione Python corrispondente. ## Quick Start Esegui semplicemente: ```batch RUN.bat ``` Il batch rileva automaticamente se hai ODBC Access 32-bit o 64-bit e usa la versione Python appropriata. **Esempio output**: ``` Rilevato ODBC Access 64-bit Uso Python Embedded 64-bit ``` Il processo scaricherà ~5GB di dati IMDb, li processerà e genererà il database Access finale in ~70-80 minuti. **Funziona da qualsiasi posizione**: Puoi eseguire `C:\path\to\ImdbUpdate\RUN.bat` anche da altre directory. **Output atteso**: - Database SQLite intermedio in `Temp/imdb_processing.db` (~2-3GB) - Database Access finale in `Temp/db_split_IMDB.accdb` (~500MB, ~1.25M record) - Database copiato automaticamente nelle destinazioni configurate - Export automatico in GemmaLoader.accdb (reparto Acquisti) - Log dettagliato in `logs/imdb_update_YYYYMMDD_HHMMSS.log` **Esecuzioni successive** (con file già scaricati): ```batch RUN.bat --skip-download ``` ### Parametri Opzionali **Mostra aiuto**: ```batch RUN.bat --help ``` Mostra tutti i parametri disponibili con esempi d'uso. **Parametri disponibili**: - `--skip-download` - Salta download, usa file esistenti in `Temp/` Utile per rielaborare dati già scaricati senza ridownload (~5GB risparmiati) - `--keep-temp` - Mantiene file temporanei al termine Default: pulisce automaticamente (~15GB risparmiati) Utile per debug o analisi intermedia - `--debug` - Mantiene finestra CMD aperta al termine Default: chiude automaticamente (ideale per schedulazioni) Utile per verificare output ed eventuali errori **Esempi combinati**: ```batch RUN.bat --skip-download --debug RUN.bat --keep-temp --debug ``` ## Struttura Progetto ``` ImdbUpdate/ ├── python64/ # Python Embedded 64-bit (~125MB con dipendenze) │ ├── python.exe │ ├── python311.dll │ ├── python311._pth # Configurazione import paths │ ├── Lib/site-packages/ # Dipendenze installate │ └── Scripts/ # pip, wheel, setuptools ├── python32/ # Python Embedded 32-bit (~120MB con dipendenze) │ ├── python.exe │ ├── python311.dll │ ├── python311._pth # Configurazione import paths │ ├── Lib/site-packages/ # Dipendenze installate │ └── Scripts/ # pip, wheel, setuptools ├── Empty/ # Template database Access con indici │ └── db_split_IMDB.accdb # Master con struttura e indici TI/TO/REGISTA ├── Temp/ # File temporanei (creata automaticamente) ├── logs/ # Log esecuzioni ├── src/ │ ├── __init__.py │ ├── downloader.py # Download e decompressione │ ├── database.py # Gestione SQLite │ ├── processor.py # Query SQL e processamento │ └── access_exporter.py # Export verso Access (preserva indici) ├── config.py # Configurazione ├── main.py # Script principale ├── requirements.txt # Riferimento dipendenze ├── RUN.bat # Launcher con auto-detect ODBC └── README.md ``` ## Utilizzo ### Esecuzione completa ```batch RUN.bat ``` ### Opzioni avanzate ```batch # Salta download (usa file esistenti in Temp/) RUN.bat --skip-download # Mantieni file temporanei (disabilita auto-cleanup) RUN.bat --keep-temp # Combina opzioni RUN.bat --skip-download --keep-temp ``` **Note**: - Di default, il sistema **pulisce automaticamente** tutti i file temporanei al termine (~15GB liberati) - Elimina anche il database Access finale (~500MB) - già copiato nelle destinazioni configurate - All'avvio, pulisce automaticamente eventuali file residui da esecuzioni precedenti interrotte - Il progetto torna alle dimensioni minime (~126MB) dopo ogni esecuzione ### Esecuzione diretta Python (opzionale) ```batch REM Con Python 64-bit python64\python.exe main.py python64\python.exe main.py --skip-download REM Con Python 32-bit python32\python.exe main.py python32\python.exe main.py --keep-temp ``` ## Flusso di Lavoro 0. **Cleanup iniziale**: Pulisce eventuali file residui da esecuzioni precedenti (inclusi database Access) 1. **Preparazione**: Crea/pulisce directory `Temp/` 2. **Download**: Scarica 7 dataset IMDb (file .gz) - ~5GB 3. **Decompressione**: Estrae file .tsv e rinomina in .txt - ~8GB 4. **Import SQLite**: Carica dati in database SQLite - ~2-3GB 5. **Processamento**: Esegue query SQL per aggregare dati 6. **Export Access**: Crea `db_split_IMDB.accdb` finale - ~500MB 7. **Distribuzione**: Copia database nelle destinazioni configurate 8. **Import GemmaLoader**: Export automatico per reparto Acquisti (opzionale) 9. **Log**: Scrive file log con timestamp 10. **Cleanup finale**: Pulisce automaticamente TUTTI i file temporanei (~15GB liberati) - progetto torna a ~126MB ## Configurazione Modifica [config.py](config.py) per personalizzare: - `EXPORT_PATHS`: Destinazioni copia finale - `GEMMA_LOADER_PATH`: Path GemmaLoader.accdb - `LOG_DIR`: Directory log - `MAX_DIRECTORS`: Numero max registi (default: 5) - `MAX_ACTORS`: Numero max attori (default: 5) - `CHUNK_SIZE`: Righe per batch import (default: 100000) ## Dataset IMDb Il progetto scarica automaticamente da https://datasets.imdbws.com: - `name.basics.tsv.gz` - Informazioni persone - `title.akas.tsv.gz` - Titoli alternativi/traduzioni - `title.basics.tsv.gz` - Informazioni base titoli - `title.crew.tsv.gz` - Crew (non usato nelle query) - `title.episode.tsv.gz` - Episodi serie TV (non usato) - `title.principals.tsv.gz` - Cast e crew principali - `title.ratings.tsv.gz` - Voti e votanti ## Differenze rispetto al VBA ### Query Ottimizzate **VBA** (loop iterativo): ```vb For iDir = 1 To 5 db.Execute("SELECT ... INTO temp2 ...") db.Execute("UPDATE ...") db.Execute("DELETE ...") Next iDir ``` **Python** (singola query): ```sql SELECT tconst, GROUP_CONCAT(primaryName, ', ') as directors FROM ( SELECT tconst, primaryName, ROW_NUMBER() OVER (PARTITION BY tconst ORDER BY ordering) as rn FROM title_principals_originale WHERE category = 'director' ) WHERE rn <= 5 GROUP BY tconst ``` ### Gestione NULL **VBA**: `IIf([field]='\N', Null, [field])` **Python**: `NULLIF(field, '\N')` o conversione automatica durante import ### Decimal Separator **VBA**: `Replace([averageRating], '.', ',')` (localizzazione italiana) **Python**: Mantiene formato standard (punto decimale) > **Nota**: Se necessario formato italiano, modificare query in [processor.py](src/processor.py:124) ## Troubleshooting ### Errore: Python Embedded non trovato ``` ERRORE: python64\python.exe non trovato! ``` **Soluzione**: Verifica che le cartelle `python32/` e `python64/` esistano e contengano `python.exe`. Se mancano, il progetto è incompleto. ### Errore: ODBC Driver non trovato ``` [Microsoft][ODBC Driver Manager] Data source name not found ``` **Soluzione**: Installa Microsoft Access Database Engine: - [64-bit](https://www.microsoft.com/en-us/download/details.aspx?id=54920) (raccomandato) - [32-bit](https://www.microsoft.com/en-us/download/details.aspx?id=13255) **Nota**: Deve corrispondere all'architettura di Python (usa `python --version` per verificare). ### Errore: Template Access non trovato ``` FileNotFoundError: Empty/db_split_IMDB.accdb ``` **Soluzione**: ```batch mkdir Empty REM Copia db_split_IMDB.accdb vuoto da backup in Empty/ ``` **IMPORTANTE**: Il template deve avere: - Tabella IMDB con struttura corretta (vedi [access_exporter.py](src/access_exporter.py) per schema) - Indici su campi: TI, TO, REGISTA (per performance query) Il sistema usa DELETE FROM invece di DROP TABLE per preservare questi indici. ### Download Interrotto Se il download si interrompe: ```batch rmdir /s Temp RUN.bat ``` Il sistema ripartirà da capo scaricando nuovamente tutti i file. ### Errore: Import GemmaLoader Fallisce ``` ERROR - Errore import GemmaLoader: '(sconosciuto)' non è un percorso valido ``` **Cause comuni**: - Percorso di rete non accessibile - File GemmaLoader.accdb aperto da altro utente - Password errata in [config.py](config.py) - Mancanza di permessi di scrittura **Soluzione**: 1. Verifica percorso: `dir \\mediaset.it\cologno\icr_acquisti\GemmaLoader\` 2. Chiudi Access se aperto 3. Verifica password in [config.py](config.py) (GEMMA_LOADER_PASSWORD) ### Processo Bloccato Durante Import Se il processo si blocca durante "Import dati in SQLite" per più di 2 ore: 1. Verifica progressione nel log: `type logs\imdb_update_*.log` 2. Se realmente bloccato, interrompi con Ctrl+C 3. Elimina `Temp/` e riprova 4. Considera riduzione `CHUNK_SIZE` in [config.py](config.py) se problemi di memoria ### File Temp/ Troppo Grande Se lo spazio disco si esaurisce: 1. Verifica spazio libero: `dir C:\ | find "byte"` 2. Elimina file temporanei vecchi in `Temp/` 3. Considera spostare `TEMP_DIR` in [config.py](config.py) su disco con più spazio ## Performance ### Evoluzione Performance | Fase | VBA Original | Python v1.0 (problematico) | Python v1.1 (attuale) | Best Speedup | |------|--------------|---------------------------|----------------------|--------------| | Download | 20 min | 15 min | 1.5 min | **13x** | | Import | 30 min | 10 min (stimato) | 55 min | 0.5x | | Processing | 120 min | 40+ min (bloccato) | 6-10 min | **12-20x** | | Export | 10 min | 8 min | 8 min | 1.25x | | **TOTALE** | **180 min** | **N/A (bloccava)** | **70-80 min** | **2.3x** | **Note**: - **Download**: Migliorato drasticamente con ottimizzazioni requests - **Import**: Più lento del previsto a causa di title_principals (60M righe, ~3.5GB), ma progredisce costantemente - **Processing**: Risolto blocco con UPDATE...FROM + indici invece di subquery correlate - **Export**: Stabile con streaming in batch > *Tempi misurati su: Windows 10, i7-8700, 16GB RAM, SSD, 100Mbps* ## Funzionalità Avanzate ### Provider OTT (Streaming) Il sistema aggiorna automaticamente il campo `OTT_EMESSO` con informazioni sui provider streaming (Netflix, Prime Video, Disney+, ecc.) leggendo da un database esterno `db_split_OTT.accdb`. Questa funzionalità permette di sapere su quale piattaforma ogni titolo è disponibile. ### Export GemmaLoader Il database finale viene automaticamente copiato in `GemmaLoader.accdb` per l'utilizzo da parte del reparto Acquisti. L'operazione avviene in streaming per gestire efficacemente il trasferimento di ~1.25M record su percorsi di rete. ## Limiti Noti 1. **Windows Only**: Export Access richiede ODBC Driver disponibile solo su Windows. 2. **Memoria**: Dataset `title.principals` può richiedere ~4GB RAM durante import. Usa `CHUNK_SIZE` in [config.py](config.py) per controllare uso memoria. 3. **Percorsi di Rete**: Le funzionalità OTT e GemmaLoader richiedono accesso a percorsi di rete aziendali configurati in [config.py](config.py). ## Portabilità e Trasferimento Il progetto è completamente portabile grazie a Python Embedded: 1. **Copia l'intera cartella** su qualsiasi PC Windows 2. **Nessun setup richiesto**: Non serve installare Python o dipendenze 3. **Esegui da qualsiasi posizione**: `C:\path\to\ImdbUpdate\RUN.bat` funziona sempre **Dimensioni progetto pulito** (pronto per trasferimento): - Python Embedded 64-bit + dipendenze: ~125 MB - Python Embedded 32-bit + dipendenze: ~120 MB - Codice sorgente: <1 MB - Template Access: ~500 KB - **Totale**: ~246 MB (include entrambe le versioni Python per massima compatibilità) Il sistema si autopulisce automaticamente alla fine dell'esecuzione, eliminando: - File IMDb scaricati (~5GB compressi) - File estratti (~8GB) - Database SQLite intermedio (~2-3GB) - Database Access finale (~500MB) - già copiato nelle destinazioni **Risultato finale**: Progetto torna completamente alle dimensioni minime (~126MB), pronto per trasferimento o nuova esecuzione. ## FAQ **Q: Quanto spazio disco serve?** A: ~15 GB temporanei durante l'esecuzione (automaticamente eliminati al termine). Il progetto pulito occupa ~246 MB (include Python 32-bit e 64-bit). **Q: Perché due versioni di Python?** A: Massima compatibilità. I PC con Office 32-bit hanno ODBC 32-bit e richiedono Python 32-bit. Il batch rileva automaticamente la versione corretta. **Q: Quanto tempo richiede il processo completo?** A: ~70-80 minuti per l'esecuzione completa. Con `--skip-download` (file già scaricati): ~60-70 minuti. **Q: Posso interrompere e riprendere il processo?** A: No, il processo è atomico. Se interrotto, riavvia `RUN.bat` - il sistema pulirà automaticamente file incompleti all'avvio. **Q: Il database finale quanto pesa?** A: ~500 MB (Access) con ~1.25M record. Il database SQLite intermedio occupa ~2-3GB. **Q: Serve sempre connessione internet?** A: Sì per il download dei dataset IMDb (~5GB). Usa `--skip-download` se hai già i file in `Temp/`. **Q: Come verifico che il processo sia completato correttamente?** A: Controlla il log in `logs/` per la riga "Completato con successo". Verifica che `Temp/db_split_IMDB.accdb` contenga ~1.25M record nella tabella IMDB. **Q: Cosa fare se il test GemmaLoader fallisce con errore di percorso?** A: Verifica che il percorso di rete sia accessibile e che il file `GemmaLoader.accdb` non sia aperto da altri utenti. ## Contributi Per modifiche o bug, apri issue su repository interno. ## Licenza Interno Mediaset. Non distribuire esternamente. ## Autore Conversione Python: Claude AI VBA Originale: Mauro Gagliardi --- **Versione**: 2.1.0 (Python Embedded Dual-Architecture) **Data**: Gennaio 2026