[Gfoss] problema QGIS - Spatialite

a.furieri a lqt.it a.furieri a lqt.it
Gio 17 Lug 2014 14:50:46 CEST


On Thu, 17 Jul 2014 14:14:13 +0200, Luca Lanteri wrote:
> Ciao a tutti,
>
> ho notato un piccolo problema con l'accoppiata QGIS-Spatialite.
> Se creo un nuovo layer geometrico spatialite e successivamente
> aggiungo dei campi utilizzando: 
>
> ALTER TABLE xxx ADD column yyy TEXT 
>
> la nuova colonna non viene vista da QGIS. Ho provato facendo un 
> vacuum
> del DB, riavviando QGIS ma nisba.
> Qualcuno conferma il problema o è una cosa mia locale ?
>

Ciao Luca,

il dataprovider di QGIS impone l'obbligo di comunicare in
anticipo svariate informazioni relative al layer al momento
in cui viene aperto / connesso:
- il tipo delle geometrie
- il relativo srid
- il total extent
- il numero complessivo delle features
- l'esatto data-type per ciascuna colonna/attributo; ed e'
   proprio qua che casca l'asino :-)
   notoriamente SQLite e' stato volutamente progettato ed
   implementato in modo tale che tutte le colonne (eccetto
   quelle usate per le Primary Keys) siano assolutamente
   "typeless"; insomma il modello concettuale alla base di
   SQLite e quello supportato da QGIS qua fanno completamente
   a pugni, siamo esattamente agli antipodi.

conseguenza pratica:
--------------------
per riuscire a passare a QGIS tutte le informazioni di
cui ha tassativamente bisogno per riuscire a gestire il
layer, occorre fare un "full tablescan" esplorativo
(lettura di tutta la tavola dalla prima fino all'ultima
riga), in modo tale da valutare dinamicamente i contenuti
effettivi.

ovviamente un approccio cosi' semplicistico funziona bene
solo per datasets "giocattolo" (max qualche migliaia di
righe); se provi ad aprire un dataset "tosto" con milioni
di righe il "full tablescan" preliminare porterebbe via
sicuramente molti minuti ... forse addirittura decine di
minuti ... e questo accadrebbe tutte le volte che QGIS
prova a stabilire una connessione con quella tavola/layer.

approccio piu' "smart":
-----------------------
SpatiaLite gestisce semi-automaticamente tutta una serie
di meta-tavole che contengono dei riepiloghi statistici;
in questo modo basta salvare una volta per tutte il
risultato del "full tablescan", e tutte le connessioni
successive avverrano in modo istantaneo, anche per tavole
contenenti milioni di righe.
per rendere ancora piu' "smart" l'approccio, spatialite
intercetta tramite triggers tutti gli eventi SQL che possono
alterare il contenuto di una tavola (INSERT/UPDATE/DELETE);
e quindi e' perfettamente in grado di sapere se/quando le
statistiche "congelate" siano ancora valide oppure richiedano
di essere aggiornate.
QGIS comunque adotta sempre l'approccio OPTIMISTIC: se
le statistiche esistono, usa comunque quel che trova fidandosi
che sia sempre valido; se vuoi puoi comunque chiedere
di aggiornare le statistiche non piu' valide; c'e' un
apposito pulsantino nel dialog box di connessione dei layers.

------------------

e finalmente arriviamo all'ALTER TABLE ADD COLUMN

a differenza di INSERT/UPDATE/DELETE, questo evento non
e' intercettabile tramite triggers SQL.
e quindi le statistiche continuano ad apparire valide,
anche se di fatto non coprono la colonna aggiunta in
seguito.
eccoti spiegato perche' non riesci a vedere la nuova
colonna che hai aggiunto: accade perche' non e' descritta
nel riepilogo statistico, mentre il dataprovider di
QGIS si basa solo sui riepiloghi per determinare
quale sia la struttura della tavola layer.

soluzione:
----------
p.es. puoi usare la versione test di spatialite_gui
http://www.gaia-gis.it/gaia-sins/windows-bin-x86-test/spatialite_gui-1.8,0-devel-win.x86.7z
dopo di che esegui questi due statements SQL:

SELECT InvalidateLayerStatistics('mio_layer');
SELECT UpdateLayerStatistics('mio_layer');

se invece hai a disposizione solo versioni precedenti
che non supportano InvalidateLayerStatistics(), puoi
comunque aggirare l'ostacolo in quest'altro modo:

UPDATE geometry_columns_statistics
SET last_verified = NULL
WHERE f_table_name = 'mio_layer';
SELECT UpdateLayerStatistics('mio_layer');

in entrambi i casi otterrai sempre il medesimo
effetto; tutte le statistiche di supporto per
quella tavola/layer verranno prima invalidate,
e quindi successivamente aggiornate.
e finalmente anche la colonna che hai aggiunto
con la ALTER TABLE ADD COLUMN risultera' visibile
anche a QGIS

ciao Sandro



Maggiori informazioni sulla lista Gfoss