[Gfoss] problemi con indici spaziali sqlite

Ciao a tutti,

sto sbattendo la testa contro alcuni problemi con gli indici spaziali di spatialite.
In diversi casi ho la sensazione che gli indici spaziali di alcuni miei layer siano corrotti. Me ne accorgo perché cercando di interrogare un layer lo strumento interrogazione non “vede” gli oggetti. Se elimino e ricreo l’indice tutto torna a funzionare. Vorrei però evitare di dover far fare quest’operazione agli utenti che utilizzano il mio db perché mi rimane difficile spiegarli come farlo.
Sapete darmi se esiste un modo semplice per risolvere il problema, o se (ancora meglio) posso fare la ricostruzione degli indici in modo automatico ?

Tra l’altro l’unico modo che ho trovato per ricreare gli indici senza scrivere codice SQL e con QSpatialite, che però si rifiuta di aprire i DB creati con DBmanager dicendomi che il db non è un db Spatialite valido. In alcuni casi dicendogli di correggere torna tutto a posto, in altri casi no.

grazie in anticipo

Luca

L’automatismo dipende dai gradi di liberta’ che hai.
E quindi dall’ambiente in cui ti muovi e che tipo di operazioni devi eseguire.

Io pero’ cercherei di capire come vai l’indice si rovina.

Interessante questo fatto che vi sia una distonia tra qspatialite e dbmanager.

Sospetto che manchi qualche trigger.
:slight_smile:

Ovvero un db spatialite DOP prevede la assegnazione di un certo numero di triggers che svolgono alcuni compiti tra cui anche quelli di tenere llineati i dati che uno inserisce / rimuove / aggiorna con la tabella di indice spaziale.

Se pero’ la creazione del db spatialite è eseguita con procedure “cinesi” ,

il DB non è DOP e quindi magari non aggiorna l’indice quando inserisci (ad esempio).

E questo potrebbe spiegare la scomparsa di certi dati.

Tieni presente che cio’ che conta è l’ambiente che cra materialmente il DB ovvero che lo inizializza, non l’ambiente che lo usa poi.

A margine, è interessante questo fatto che qspatialite e dbmanager non sono allineati sulla costruzione del db spatialite.

Questa cosa vorrei capirla meglio:
puoi fornire maggiori dettagli:
versione di qgis, versione di spatialite, sistema operativo ?

···

Grazie,

Andrea.

Il giorno 20 febbraio 2014 15:31, Luca Lanteri <mescal72@gmail.com> ha scritto:

Ciao a tutti,

sto sbattendo la testa contro alcuni problemi con gli indici spaziali di spatialite.
In diversi casi ho la sensazione che gli indici spaziali di alcuni miei layer siano corrotti. Me ne accorgo perché cercando di interrogare un layer lo strumento interrogazione non “vede” gli oggetti. Se elimino e ricreo l’indice tutto torna a funzionare. Vorrei però evitare di dover far fare quest’operazione agli utenti che utilizzano il mio db perché mi rimane difficile spiegarli come farlo.
Sapete darmi se esiste un modo semplice per risolvere il problema, o se (ancora meglio) posso fare la ricostruzione degli indici in modo automatico ?

Tra l’altro l’unico modo che ho trovato per ricreare gli indici senza scrivere codice SQL e con QSpatialite, che però si rifiuta di aprire i DB creati con DBmanager dicendomi che il db non è un db Spatialite valido. In alcuni casi dicendogli di correggere torna tutto a posto, in altri casi no.

grazie in anticipo

Luca


Gfoss@lists.gfoss.it
http://lists.gfoss.it/cgi-bin/mailman/listinfo/gfoss
Questa e’ una lista di discussione pubblica aperta a tutti.
I messaggi di questa lista non hanno relazione diretta con le posizioni dell’Associazione GFOSS.it.
666 iscritti al 22.7.2013

Andrea Peri
. . . . . . . . .
qwerty àèìòù

Allora, ti rispondo al volo adesso e poi con più calma ti darò qualche dettaglio in più.
I DB in genere li creo con QGIS. Alcuni li ho fatti con la versione 2.0 (non mi ricordo se su win o su linux),altri sono stati fatti con quella precedente (1.8).
Su linux ho dovuto usare una versione compilata e non quella dei repo per poter leggere la nuova versione di spatialite.
Non ho una casistica ampia certa per capire con chiarezza dove sta il problema (e non ho neanche conoscenze approfondite di spatialite). Quello che però ho visto è che mi si è ripresentata più volte la necessità di dover ricreare gli indici perché il DB funzionasse correttamente, in particolare su una tavola dove la geometria non veniva inserita da qgis ma calcolata mediante un trigger sulla base di un’altra geometria.

adesso scappo,
grazie mille

···

Il giorno 20 febbraio 2014 15:41, Andrea Peri <aperi2007@gmail.com> ha scritto:

L’automatismo dipende dai gradi di liberta’ che hai.
E quindi dall’ambiente in cui ti muovi e che tipo di operazioni devi eseguire.

Io pero’ cercherei di capire come vai l’indice si rovina.

Interessante questo fatto che vi sia una distonia tra qspatialite e dbmanager.

Sospetto che manchi qualche trigger.
:slight_smile:

Ovvero un db spatialite DOP prevede la assegnazione di un certo numero di triggers che svolgono alcuni compiti tra cui anche quelli di tenere llineati i dati che uno inserisce / rimuove / aggiorna con la tabella di indice spaziale.

Se pero’ la creazione del db spatialite è eseguita con procedure “cinesi” ,

il DB non è DOP e quindi magari non aggiorna l’indice quando inserisci (ad esempio).

E questo potrebbe spiegare la scomparsa di certi dati.

Tieni presente che cio’ che conta è l’ambiente che cra materialmente il DB ovvero che lo inizializza, non l’ambiente che lo usa poi.

A margine, è interessante questo fatto che qspatialite e dbmanager non sono allineati sulla costruzione del db spatialite.

Questa cosa vorrei capirla meglio:
puoi fornire maggiori dettagli:
versione di qgis, versione di spatialite, sistema operativo ?

Grazie,

Andrea.

Il giorno 20 febbraio 2014 15:31, Luca Lanteri <mescal72@gmail.com> ha scritto:

Ciao a tutti,

sto sbattendo la testa contro alcuni problemi con gli indici spaziali di spatialite.
In diversi casi ho la sensazione che gli indici spaziali di alcuni miei layer siano corrotti. Me ne accorgo perché cercando di interrogare un layer lo strumento interrogazione non “vede” gli oggetti. Se elimino e ricreo l’indice tutto torna a funzionare. Vorrei però evitare di dover far fare quest’operazione agli utenti che utilizzano il mio db perché mi rimane difficile spiegarli come farlo.
Sapete darmi se esiste un modo semplice per risolvere il problema, o se (ancora meglio) posso fare la ricostruzione degli indici in modo automatico ?

Tra l’altro l’unico modo che ho trovato per ricreare gli indici senza scrivere codice SQL e con QSpatialite, che però si rifiuta di aprire i DB creati con DBmanager dicendomi che il db non è un db Spatialite valido. In alcuni casi dicendogli di correggere torna tutto a posto, in altri casi no.

grazie in anticipo

Luca


Gfoss@lists.gfoss.it
http://lists.gfoss.it/cgi-bin/mailman/listinfo/gfoss
Questa e’ una lista di discussione pubblica aperta a tutti.
I messaggi di questa lista non hanno relazione diretta con le posizioni dell’Associazione GFOSS.it.
666 iscritti al 22.7.2013

Andrea Peri
. . . . . . . . .
qwerty àèìòù

Come giustamente gia' ricordava Andrea, il corretto funzionamento
degli Spatial Index su SQLite/SpatiaLite e' interamente basato
su alcuni Triggers; se quei triggers mancano (oppure sono stati
alterati, o se sono dichiarati in modo "artistico") lo Spatial
Index sara' sicuramente soggetto a problemi di out-of-sync
piu' o meno gravi..

il secondo elemento critico per il buon funzionamento degli
Spatial Index e' l'assoluta coerenza ed immutabilita dei ROWIDs.

quindi in tutti questi casi lo Spatial Index puo' soffrire di
pesanti problemi di out-of-sync come quelli descritti da Luca:
a) tavola senza una PRIMARY KEY
b) tavola con una PRIMARY KEY che non consista in un'unica colonna
    di tipo INTEGER (p.es. TEXT, oppure multi-column)
c) tavola contenete una colonna "fisica" di nome ROWID
d) a partire dalla versione 3.8.x di SQLite: tavola creata con
    la clausola WITHOUT ROWID

per ulteriori approfondimenti tecnici (compresi gli stumenti
standard di check/repair, disponibili anche come funzioni SQL):

http://www.gaia-gis.it/gaia-sins/SpatialIndex-Update.pdf
https://www.gaia-gis.it/fossil/libspatialite/wiki?name=Shadowed+ROWID+issues

ciao Sandro

On Thu, 20 Feb 2014 15:41:12 +0100, Andrea Peri wrote:

L'automatismo dipende dai gradi di liberta' che hai.
E quindi dall'ambiente in cui ti muovi e che tipo di operazioni devi
eseguire.

Io pero' cercherei di capire come vai l'indice si rovina.

Interessante questo fatto che vi sia una distonia tra qspatialite e
dbmanager.

Sospetto che manchi qualche trigger.
:slight_smile:

Ovvero un db spatialite DOP prevede la assegnazione di un certo numero
di triggers che svolgono alcuni compiti tra cui anche quelli di tenere
llineati i dati che uno inserisce / rimuove / aggiorna con la tabella
di indice spaziale.

Se pero' la creazione del db spatialite è eseguita con procedure
"cinesi" ,

il DB non è DOP e quindi magari non aggiorna l'indice quando
inserisci (ad esempio).

E questo potrebbe spiegare la scomparsa di certi dati.

Tieni presente che cio' che conta è l'ambiente che cra materialmente
il DB ovvero che lo inizializza, non l'ambiente che lo usa poi.

A margine, è interessante questo fatto che qspatialite e dbmanager
non sono allineati sulla costruzione del db spatialite.

Questa cosa vorrei capirla meglio:
puoi fornire maggiori dettagli:
versione di qgis, versione di spatialite, sistema operativo ?

Grazie,

Andrea.

Il giorno 20 febbraio 2014 15:31, Luca Lanteri ha scritto:

Ciao a tutti,

sto sbattendo la testa contro alcuni problemi con gli indici
spaziali di spatialite.
In diversi casi ho la sensazione che gli indici spaziali di alcuni
miei layer siano corrotti. Me ne accorgo perché cercando di
interrogare un layer lo strumento interrogazione non "vede" gli
oggetti. Se elimino e ricreo l'indice tutto torna a funzionare.
Vorrei però evitare di dover far fare quest'operazione agli utenti
che utilizzano il mio db perché mi rimane difficile spiegarli come
farlo.
Sapete darmi se esiste un modo semplice per risolvere il problema, o
se (ancora meglio) posso fare la ricostruzione degli indici in modo
automatico ?

Tra l'altro l'unico modo che ho trovato per ricreare gli indici
senza scrivere codice SQL e con QSpatialite, che però si rifiuta di
aprire i DB creati con DBmanager dicendomi che il db non è un db
Spatialite valido. In alcuni casi dicendogli di correggere torna
tutto a posto, in altri casi no.

grazie in anticipo

Luca
_______________________________________________
Gfoss@lists.gfoss.it [1]
http://lists.gfoss.it/cgi-bin/mailman/listinfo/gfoss [2]
Questa e' una lista di discussione pubblica aperta a tutti.
I messaggi di questa lista non hanno relazione diretta con le
posizioni dell'Associazione GFOSS.it.
666 iscritti al 22.7.2013

On Thu, 20 Feb 2014 16:18:50 +0100, Luca Lanteri wrote:

Quello che però ho visto è che mi si è ripresentata più volte la
necessità di dover ricreare gli indici perché il DB funzionasse
correttamente, in particolare su una tavola dove la geometria non
veniva inserita da qgis ma calcolata mediante un trigger sulla base di
un'altra geometria.

e probabilmente l'intoppo e' proprio qua.
su SpatiaLite le geometrie devono sempre venire create invocando la
funzione SQL AddGeometryColumn() [oppure RecoverGeometryColumn()],
perche' e' l'unico modo sicuro per garantire che tutti i Triggers
necessari vengano creati nel modo corretto.

qualsiasi geometria che invece venga semplicemente creata andando
ad inserire direttamente una riga su "geometry_columns" risultera'
inevitabilmente "zoppa".
proprio perche' in questo modo verra' a mancare il supporto dei
Triggers, che e' assolutamente idispensabile per assicurare il
corretto aggiornamento degli R*Trees ogni volta che si effettua
una INSERT / UPDATE / DELETE.

ciao Sandro

grazie Sandro e Andrea per gli ottimi riferimenti da cui partire

···

Il giorno 20 febbraio 2014 16:34, <a.furieri@lqt.it> ha scritto:

On Thu, 20 Feb 2014 16:18:50 +0100, Luca Lanteri wrote:

Quello che però ho visto è che mi si è ripresentata più volte la
necessità di dover ricreare gli indici perché il DB funzionasse
correttamente, in particolare su una tavola dove la geometria non
veniva inserita da qgis ma calcolata mediante un trigger sulla base di
un’altra geometria.

e probabilmente l’intoppo e’ proprio qua.
su SpatiaLite le geometrie devono sempre venire create invocando la
funzione SQL AddGeometryColumn() [oppure RecoverGeometryColumn()],
perche’ e’ l’unico modo sicuro per garantire che tutti i Triggers
necessari vengano creati nel modo corretto.
qualsiasi geometria che invece venga semplicemente creata andando
ad inserire direttamente una riga su “geometry_columns” risultera’
inevitabilmente “zoppa”.
proprio perche’ in questo modo verra’ a mancare il supporto dei
Triggers, che e’ assolutamente idispensabile per assicurare il
corretto aggiornamento degli R*Trees ogni volta che si effettua
una INSERT / UPDATE / DELETE.

Io creo la colonna della geometria con RecoverGeometryColumn(), poi popolo semplicemente i dati mediante un update della colonna geometrica, prendendo la geometria da un’atra tabella invece che dall’interfaccia di qgis. I trigger che popolano gli indici dovrebbero essere scatenati tanto dal mio update quanto da un inserimento diretto in QGIS, no ?

Spero che cosi sia, visto che sto utilizzando Sqlite proprio per poter utilizzare le funzionalità dei trigger.

A questo punto, qual’è lo strumento migliore per creare un DB Spatialite DOC, come lo chiamava Andrea ?
Io li ho sempre creati da QGIS, che tra l’altro nella versione 2.0 mi pare ci metta un tempo eterno (non vorrei che il problema fosse proprio li). Con la 2.1 i tempi di creazione sono decisamente più sensati.

Esiste un modo per verificare se un DB Spatialite è corretto ed ha tutti i trigger e gli indici a posto? Se ci fossero problemi esiste il modo di farne un repair ?

a presto
Luca

Il giorno 20 febbraio 2014 21:44, Luca Lanteri <mescal72@gmail.com> ha
scritto:

grazie Sandro e Andrea per gli ottimi riferimenti da cui partire

Il giorno 20 febbraio 2014 16:34, <a.furieri@lqt.it> ha scritto:

On Thu, 20 Feb 2014 16:18:50 +0100, Luca Lanteri wrote:

Quello che però ho visto è che mi si è ripresentata più volte la
necessità di dover ricreare gli indici perché il DB funzionasse
correttamente, in particolare su una tavola dove la geometria non
veniva inserita da qgis ma calcolata mediante un trigger sulla base di
un'altra geometria.

e probabilmente l'intoppo e' proprio qua.
su SpatiaLite le geometrie devono sempre venire create invocando la
funzione SQL AddGeometryColumn() [oppure RecoverGeometryColumn()],
perche' e' l'unico modo sicuro per garantire che tutti i Triggers
necessari vengano creati nel modo corretto.
qualsiasi geometria che invece venga semplicemente creata andando
ad inserire direttamente una riga su "geometry_columns" risultera'
inevitabilmente "zoppa".
proprio perche' in questo modo verra' a mancare il supporto dei
Triggers, che e' assolutamente idispensabile per assicurare il
corretto aggiornamento degli R*Trees ogni volta che si effettua
una INSERT / UPDATE / DELETE.

Infatti anche io credo che sia un problema di triggers.

Io creo la colonna della geometria con RecoverGeometryColumn(),

No, la recovery funziona se hai creato la tabella con un comando del tipo:

create table pippo as select campo1,campo2,...,geometria from pluto;

inoltre stai attento che se scrivi:

create table pippo as select * from pluto;

non funziona bene.
sempre meglio esplicitare i nomi dei campi, mai affidarsi alla scorciatoia
" * "

Quindi se tu avessi fatto qualcosa del tipo:

create table pippo (campo 1 integer, campo 2 blob);
e poi gli applichi una :

select recoverygeometrycolumn('pippo','geometria',...);
probabilmente è qui che vi è il problema.

La procedura corretta è creare la tabella senza il campo "geometria" e poi
aggiungerlo con la sintassi:

select Addgeometrycolumns(....);

poi popolo semplicemente i dati mediante un update della colonna
geometrica, prendendo la geometria da un'atra tabella invece che
dall'interfaccia di qgis. I trigger che popolano gli indici dovrebbero
essere scatenati tanto dal mio update quanto da un inserimento diretto in
QGIS, no ?

Spero che cosi sia, visto che sto utilizzando Sqlite proprio per poter
utilizzare le funzionalità dei trigger.

Avrei una altra ipotesi al riguardo.
Una ipotesi che mi deriva da un episodio che ho affrontato qualche
settimana fa'.
In tale occasione , avevo definito un trigger su un db spatialite, per
garantire che a fronte di certi valori su un campo, venisse popolato altri
campi.

Quando andavo a popolare questo db con qgis, mi accorsi che in realta' il
trigger non si scatenava.

Purtroppo non ho ulteriormente indagato.
Presi atto che non funzionava, forse avevo sbagliato a definire il trigger,
forse era qgis che non funzizonava, fatto sta' che scelsi di seguire altre
strade e decisi di non indagare oltre.

Avrei dovuto, ma non avevo proprio il tempo.

Mi sono ricordato di quell'episodio ora, che leggo del tuo caso.
Forse potrebbe essere un ulteriore indizio che
Il codice del provider sqlite di qgis potrebbe essere stato modificato per
non scatenare i triggers.
O forse solo alcuni di essi.
(sigh)

Sicuramente è da verificare.A questo punto vedo di fare qualche prova in
questo fine settimana.

Andrea.

On Thu, 20 Feb 2014 21:44:33 +0100, Luca Lanteri wrote:

Io creo la colonna della geometria con RecoverGeometryColumn(), poi
popolo semplicemente i dati mediante un update della colonna
geometrica, prendendo la geometria da un'atra tabella invece che
dall'interfaccia di qgis. I trigger che popolano gli indici dovrebbero
essere scatenati tanto dal mio update quanto da un inserimento diretto
in QGIS, no ?

ok, almeno in teoria torna perfettamente:
- RecoverGeometryColumn() dovrebbe installare tutti i triggers
- dopo di che ogni volta che fai un'INSERT/UPDATE/DELETE l'R*Tree
   verra' immediatamente aggiornato perche' ci pensano comunque i
   triggers in modo automatico.

natualmente, tra la teoria e la pratica c'e' sempre spazio a sufficienza
perche' ci si infili in mezzo lo zoccolo bifido di Messer Satanasso :slight_smile:

Spero che cosi sia, visto che sto utilizzando Sqlite proprio per poter
utilizzare le funzionalità dei trigger.

questo fa nascere un dubbio ulteriore: i Triggers di SQLite sono basati
su una buona implementazione, ma ci sono alcuni caveats da tener di conto:
- alcune versioni molto vecchie (< 3.7.x) non dovrebbero essere in grado
   di supportare Triggers ricursivi.
   cioe', se un triggers fa partire un secondo trigger che ne scatena un
   terzo etc, con le vecchie versioni dovrebbe partire solo il primo,
   perche' poi la catena si spezza
- ma anche con le versioni recenti, c'e' comunque un limite nei livelli
   di nidificazione supportati dai triggers.
   e comunque occorre invocare esplicitamente una PRAGMA per abilitare la
   ricursivita' per i Triggers (by default e' comunque disabled).
   vedi: http://www.sqlite.org/pragma.html#pragma_recursive_triggers

A questo punto, qual'è lo strumento migliore per creare un DB
Spatialite DOC, come lo chiamava Andrea ?

naturalmente il mio non e' un parere spassionato: ma non ho comunque
il minimo dubbio. spatialite CLI oppure SpatiaLite GUI

cioe' i due strumenti piu' strettamente integrati con il DBMS, direttamente
gestiti dal medesimo gruppo di sviluppatori che segue il DBMS, e che sono
quindi sempre certamente allineati con le specifiche tecniche del DBMS via
via che vanno evolvendosi di versione in versione.
e che piu' facilmente tendono a recepire una vasta casistica di casi d'uso
che spaziono dalle micro-app per Android/smartphones fino alle piu'
complesse applicazioni ultra-professionali in contesti enterprise.

Io li ho sempre creati da QGIS, che tra l'altro nella versione 2.0 mi
pare ci metta un tempo eterno (non vorrei che il problema fosse
proprio li). Con la 2.1 i tempi di creazione sono decisamente più
sensati.

in occasione del rilascio di splite v.4.0 e' stato introdotto un
modestissimo cambiamento in una funzione SQL legata all'inizializzazione
di un nuovo DB.
modifica peraltro messa in forte rilievo nelle note di rilascio, ed
abbondamente discussa piu' e piu' volte nella ML di spatialite.
qgis 2.0 non ha supportato tempestivamente la modifica, e quindi e'
soggetto ad una discreta lentezza in fase di creazione di un nuovo DB
(anche se comunque alla fine i risultati del processo sono perfettamente
corretti); viceversa poi qgis 2.1 e' stato correttamente aggiornato,
ed ora alla fine tutto e' tornato a funzionare in modo ottimale.

Esiste un modo per verificare se un DB Spatialite è corretto ed ha
tutti i trigger e gli indici a posto?

in linea di massima non e' possibile, perche' la casistica "degli
interventi cinesi" (come li chiama Andrea) e' potenzialmente illimitata.
in caso di dubbio una chiamata (tutta di seguito) a questa coppia di
funzioni dovebbe rimettere tutti i Triggers per ciascuna colonna geometrica
correttamente a posto:
- DiscardGeometryColumn()
- RecoverGeometryColumn()

Se ci fossero problemi esiste il modo di farne un repair ?

ci sono due funzioni SQL fatte apposta per verificare/ricostruire
gli Spatial Index (quantomeno, nei casi d'uso piu' comuni e ragionevoli):
- CheckSpatialIndex()
- RepairSpatialIndex()

qua ci trovi maggiori informazioni:
http://www.gaia-gis.it/gaia-sins/SpatialIndex-Update.pdf

ciao Sandro

On Thu, 20 Feb 2014 22:09:42 +0100, Andrea Peri wrote:

In tale occasione , avevo definito un trigger su un db spatialite,
per garantire che a fronte di certi valori su un campo, venisse
popolato altri campi.

Quando andavo a popolare questo db con qgis, mi accorsi che in
realta' il trigger non si scatenava.

cosi' a lume di naso, penso che non sarebbe affatto male prendere
in considerazione le proprieta' ricorsive' dei Triggers di SQLite
facendo qualche verifica ad hoc

http://www.sqlite.org/pragma.html#pragma_recursive_triggers

a prima vista sembrerebbe che tutto possa nascere dal fatto che
by default la ricorsivita' e' sempre disabilitata; magari una
direttiva come questa potrebbe anche risolvere il problema:

PRAGMA recurvive_triggers=1

ciao Sandro

Ho dato una lettura al documento che indicavi.

Riassumendo:

prima della sqlite 3.6.18 i trigger ricorsivi non erano supporti e quindi vanno eviate versioni di sqlite cosi’ vecchie.

Nelle versioni successive, pero’ i trigger ricorsivi erano disabilitati by-default, ppunto come dicevi te.
Quindi occorre sempre inserire una clausola

PRAGMA recurvive_triggers=1

Usando gli applicativi di spatialite:
CLI e Spatialite-GUI.
Questa clausola
recursive_triggers va settata comunque o è implicita ?

Detto questo.

se un disgraziato lavora su QGIS, editando un dataset tramite la finestra degli attributi, oppure trmaite le form customized che ora qgis consente, tale clausola “recursive_triggers=1” probabilmente è a 0 , ma come puo’ fare per garantirsi di settarla a 1 ?

Qui mi sorge un dubbio serio…

E forse comincio a capire perche’ a suo tempo ebbi dei problemi…

A

···

Il giorno 20 febbraio 2014 22:31, <a.furieri@lqt.it> ha scritto:

On Thu, 20 Feb 2014 21:44:33 +0100, Luca Lanteri wrote:

Io creo la colonna della geometria con RecoverGeometryColumn(), poi
popolo semplicemente i dati mediante un update della colonna
geometrica, prendendo la geometria da un’atra tabella invece che
dall’interfaccia di qgis. I trigger che popolano gli indici dovrebbero
essere scatenati tanto dal mio update quanto da un inserimento diretto
in QGIS, no ?

ok, almeno in teoria torna perfettamente:

  • RecoverGeometryColumn() dovrebbe installare tutti i triggers
  • dopo di che ogni volta che fai un’INSERT/UPDATE/DELETE l’R*Tree
    verra’ immediatamente aggiornato perche’ ci pensano comunque i
    triggers in modo automatico.

natualmente, tra la teoria e la pratica c’e’ sempre spazio a sufficienza
perche’ ci si infili in mezzo lo zoccolo bifido di Messer Satanasso :slight_smile:

Spero che cosi sia, visto che sto utilizzando Sqlite proprio per poter
utilizzare le funzionalità dei trigger.

questo fa nascere un dubbio ulteriore: i Triggers di SQLite sono basati
su una buona implementazione, ma ci sono alcuni caveats da tener di conto:

  • alcune versioni molto vecchie (< 3.7.x) non dovrebbero essere in grado
    di supportare Triggers ricursivi.
    cioe’, se un triggers fa partire un secondo trigger che ne scatena un
    terzo etc, con le vecchie versioni dovrebbe partire solo il primo,
    perche’ poi la catena si spezza
  • ma anche con le versioni recenti, c’e’ comunque un limite nei livelli
    di nidificazione supportati dai triggers.
    e comunque occorre invocare esplicitamente una PRAGMA per abilitare la
    ricursivita’ per i Triggers (by default e’ comunque disabled).
    vedi: http://www.sqlite.org/pragma.html#pragma_recursive_triggers

A questo punto, qual’è lo strumento migliore per creare un DB
Spatialite DOC, come lo chiamava Andrea ?

naturalmente il mio non e’ un parere spassionato: ma non ho comunque
il minimo dubbio. spatialite CLI oppure SpatiaLite GUI

cioe’ i due strumenti piu’ strettamente integrati con il DBMS, direttamente
gestiti dal medesimo gruppo di sviluppatori che segue il DBMS, e che sono
quindi sempre certamente allineati con le specifiche tecniche del DBMS via
via che vanno evolvendosi di versione in versione.
e che piu’ facilmente tendono a recepire una vasta casistica di casi d’uso
che spaziono dalle micro-app per Android/smartphones fino alle piu’
complesse applicazioni ultra-professionali in contesti enterprise.

Io li ho sempre creati da QGIS, che tra l’altro nella versione 2.0 mi
pare ci metta un tempo eterno (non vorrei che il problema fosse
proprio li). Con la 2.1 i tempi di creazione sono decisamente più
sensati.

in occasione del rilascio di splite v.4.0 e’ stato introdotto un
modestissimo cambiamento in una funzione SQL legata all’inizializzazione
di un nuovo DB.
modifica peraltro messa in forte rilievo nelle note di rilascio, ed
abbondamente discussa piu’ e piu’ volte nella ML di spatialite.
qgis 2.0 non ha supportato tempestivamente la modifica, e quindi e’
soggetto ad una discreta lentezza in fase di creazione di un nuovo DB
(anche se comunque alla fine i risultati del processo sono perfettamente
corretti); viceversa poi qgis 2.1 e’ stato correttamente aggiornato,
ed ora alla fine tutto e’ tornato a funzionare in modo ottimale.

Esiste un modo per verificare se un DB Spatialite è corretto ed ha
tutti i trigger e gli indici a posto?

in linea di massima non e’ possibile, perche’ la casistica “degli
interventi cinesi” (come li chiama Andrea) e’ potenzialmente illimitata.
in caso di dubbio una chiamata (tutta di seguito) a questa coppia di
funzioni dovebbe rimettere tutti i Triggers per ciascuna colonna geometrica
correttamente a posto:

  • DiscardGeometryColumn()
  • RecoverGeometryColumn()

Se ci fossero problemi esiste il modo di farne un repair ?

ci sono due funzioni SQL fatte apposta per verificare/ricostruire
gli Spatial Index (quantomeno, nei casi d’uso piu’ comuni e ragionevoli):

  • CheckSpatialIndex()
  • RepairSpatialIndex()

qua ci trovi maggiori informazioni:
http://www.gaia-gis.it/gaia-sins/SpatialIndex-Update.pdf

ciao Sandro


Gfoss@lists.gfoss.it
http://lists.gfoss.it/cgi-bin/mailman/listinfo/gfoss
Questa e’ una lista di discussione pubblica aperta a tutti.
I messaggi di questa lista non hanno relazione diretta con le posizioni dell’Associazione GFOSS.it.
666 iscritti al 22.7.2013

Andrea Peri
. . . . . . . . .
qwerty àèìòù

On Fri, 21 Feb 2014 09:23:49 +0100, Andrea Peri wrote:

Ho dato una lettura al documento che indicavi.

Riassumendo:
prima della sqlite 3.6.18 i trigger ricorsivi non erano supporti e
quindi vanno eviate versioni di sqlite cosi' vecchie.

Nelle versioni successive, pero' i trigger ricorsivi erano
disabilitati by-default, ppunto come dicevi te.
Quindi occorre sempre inserire una clausola

PRAGMA recurvive_triggers=1

Usando gli applicativi di spatialite:
CLI e Spatialite-GUI.
Questa clausola
recursive_triggers va settata comunque o è implicita ?

con tutte le versioni attuali (CLI/GUI) e' sempre disabilitata
by default; ma per analogia con quanto gia' implementato per
l'analoga "PRAGMA foreign_keys" presumo invece che sarebbe piu'
opportuno abilitarla implicitamente.

Detto questo.

se un disgraziato lavora su QGIS, editando un dataset tramite la
finestra degli attributi, oppure trmaite le form customized che ora
qgis consente, tale clausola "recursive_triggers=1" probabilmente è a
0 , ma come puo' fare per garantirsi di settarla a 1 ?

vista l'architettura SQLite, gestire questo tipo di PRAGMA ricade
sotto la piena responsabilita' del sw che attiva la connessione:
non c'e' nessun modo per renderele permanenti.

il problema e' abbastanza facile da affrontare per tutti i tools che
gestiscono le connessioni in modo centralizzato (p.es. il data-provider
di QGIS, oppure i tool spatialite); ma nel caso p.es. dei plug-in Python
ciascun singolo plug-in e' ovviamente libero di comportarsi come meglio
crede, e non c'e' nessuna possibilita' di imporre dall'esterno un
set di comportamenti predefiniti.

Qui mi sorge un dubbio serio...

E forse comincio a capire perche' a suo tempo ebbi dei problemi...

N.B.: ed a questo proposito a me inizia a sorgere anche un ulteriore
dubbio; con tutta la proliferazione di tools e di interfacce che
iniziano a circolare, siamo sempre sicuri che il supporto per i vincoli
relazionali venga attivato in tutti i casi ?

perche' se da qualche parte c'e' un tool che apre una connessione per
conto proprio al di fuori del data-provider (p.es. in Python) che non
cura di impostare correttamente questo parametro di connessione:

PRAGMA foreign_keys=1

allora potrebbe addirittura accadere che tutti i vincoli Primary/Foreign
Key possano venire allegramente violati senza nessuna conseguenza.
e naturalmente, in caso di mancata attivazione, non funzionano neppure
le sequenze di eventi ON CASCADE ... insomma, le conseguenze potrebbero
anche avere un impatto fortemente negativo, anche peggiore di quello
dovuto a mancata attivazione del supporto ricursivo per i triggers.

ciao Sandro

Mi inserisco nella discussione per chiedere una cosa veramente banale.
Una volta attivati i recursive trigger e le foreign_keys su un database, questi rimangono attivi per quel determinato DB e solo per quello, o devo riattivarli ad ogni nuova connessione, o ancora peggio rimangono attivati su tutti i DB ?

···

Immagino che il comportamento corretto sia il primo, ma giusto per sicurezza…
grazie

Il giorno 21 febbraio 2014 09:54, <a.furieri@lqt.it> ha scritto:

On Fri, 21 Feb 2014 09:23:49 +0100, Andrea Peri wrote:

Ho dato una lettura al documento che indicavi.

Riassumendo:
prima della sqlite 3.6.18 i trigger ricorsivi non erano supporti e
quindi vanno eviate versioni di sqlite cosi’ vecchie.

Nelle versioni successive, pero’ i trigger ricorsivi erano
disabilitati by-default, ppunto come dicevi te.
Quindi occorre sempre inserire una clausola

PRAGMA recurvive_triggers=1

Usando gli applicativi di spatialite:
CLI e Spatialite-GUI.
Questa clausola
recursive_triggers va settata comunque o è implicita ?

con tutte le versioni attuali (CLI/GUI) e’ sempre disabilitata
by default; ma per analogia con quanto gia’ implementato per
l’analoga “PRAGMA foreign_keys” presumo invece che sarebbe piu’
opportuno abilitarla implicitamente.

Detto questo.

se un disgraziato lavora su QGIS, editando un dataset tramite la
finestra degli attributi, oppure trmaite le form customized che ora
qgis consente, tale clausola “recursive_triggers=1” probabilmente è a
0 , ma come puo’ fare per garantirsi di settarla a 1 ?

vista l’architettura SQLite, gestire questo tipo di PRAGMA ricade
sotto la piena responsabilita’ del sw che attiva la connessione:
non c’e’ nessun modo per renderele permanenti.

il problema e’ abbastanza facile da affrontare per tutti i tools che
gestiscono le connessioni in modo centralizzato (p.es. il data-provider
di QGIS, oppure i tool spatialite); ma nel caso p.es. dei plug-in Python
ciascun singolo plug-in e’ ovviamente libero di comportarsi come meglio
crede, e non c’e’ nessuna possibilita’ di imporre dall’esterno un
set di comportamenti predefiniti.

Qui mi sorge un dubbio serio…

E forse comincio a capire perche’ a suo tempo ebbi dei problemi…

N.B.: ed a questo proposito a me inizia a sorgere anche un ulteriore
dubbio; con tutta la proliferazione di tools e di interfacce che
iniziano a circolare, siamo sempre sicuri che il supporto per i vincoli
relazionali venga attivato in tutti i casi ?

perche’ se da qualche parte c’e’ un tool che apre una connessione per
conto proprio al di fuori del data-provider (p.es. in Python) che non
cura di impostare correttamente questo parametro di connessione:

PRAGMA foreign_keys=1

allora potrebbe addirittura accadere che tutti i vincoli Primary/Foreign
Key possano venire allegramente violati senza nessuna conseguenza.
e naturalmente, in caso di mancata attivazione, non funzionano neppure
le sequenze di eventi ON CASCADE … insomma, le conseguenze potrebbero
anche avere un impatto fortemente negativo, anche peggiore di quello
dovuto a mancata attivazione del supporto ricursivo per i triggers.

ciao Sandro


Gfoss@lists.gfoss.it
http://lists.gfoss.it/cgi-bin/mailman/listinfo/gfoss
Questa e’ una lista di discussione pubblica aperta a tutti.
I messaggi di questa lista non hanno relazione diretta con le posizioni dell’Associazione GFOSS.it.
666 iscritti al 22.7.2013

Il giorno 21 febbraio 2014 10:08, Luca Lanteri <mescal72@gmail.com> ha
scritto:

Mi inserisco nella discussione per chiedere una cosa veramente banale.
Una volta attivati i recursive trigger e le foreign_keys su un database,
questi rimangono attivi per quel determinato DB e solo per quello, o devo
riattivarli ad ogni nuova connessione, o ancora peggio rimangono attivati
su tutti i DB ?

Le PRAGMA sono attive per singola connessione (ed eventualmente con effetti
retroattivi secondo le regole più specifiche della singola PRAGMA).
http://www.sqlite.org/pragma.html

giovanni

Immagino che il comportamento corretto sia il primo, ma giusto per
sicurezza....
grazie

Il giorno 21 febbraio 2014 09:54, <a.furieri@lqt.it> ha scritto:

On Fri, 21 Feb 2014 09:23:49 +0100, Andrea Peri wrote:

Ho dato una lettura al documento che indicavi.

Riassumendo:
prima della sqlite 3.6.18 i trigger ricorsivi non erano supporti e
quindi vanno eviate versioni di sqlite cosi' vecchie.

Nelle versioni successive, pero' i trigger ricorsivi erano
disabilitati by-default, ppunto come dicevi te.
Quindi occorre sempre inserire una clausola

PRAGMA recurvive_triggers=1

Usando gli applicativi di spatialite:
CLI e Spatialite-GUI.
Questa clausola
recursive_triggers va settata comunque o è implicita ?

con tutte le versioni attuali (CLI/GUI) e' sempre disabilitata
by default; ma per analogia con quanto gia' implementato per
l'analoga "PRAGMA foreign_keys" presumo invece che sarebbe piu'
opportuno abilitarla implicitamente.

Detto questo.

se un disgraziato lavora su QGIS, editando un dataset tramite la
finestra degli attributi, oppure trmaite le form customized che ora
qgis consente, tale clausola "recursive_triggers=1" probabilmente è a
0 , ma come puo' fare per garantirsi di settarla a 1 ?

vista l'architettura SQLite, gestire questo tipo di PRAGMA ricade
sotto la piena responsabilita' del sw che attiva la connessione:
non c'e' nessun modo per renderele permanenti.

il problema e' abbastanza facile da affrontare per tutti i tools che
gestiscono le connessioni in modo centralizzato (p.es. il data-provider
di QGIS, oppure i tool spatialite); ma nel caso p.es. dei plug-in Python
ciascun singolo plug-in e' ovviamente libero di comportarsi come meglio
crede, e non c'e' nessuna possibilita' di imporre dall'esterno un
set di comportamenti predefiniti.

Qui mi sorge un dubbio serio...

E forse comincio a capire perche' a suo tempo ebbi dei problemi...

N.B.: ed a questo proposito a me inizia a sorgere anche un ulteriore
dubbio; con tutta la proliferazione di tools e di interfacce che
iniziano a circolare, siamo sempre sicuri che il supporto per i vincoli
relazionali venga attivato in tutti i casi ?

perche' se da qualche parte c'e' un tool che apre una connessione per
conto proprio al di fuori del data-provider (p.es. in Python) che non
cura di impostare correttamente questo parametro di connessione:

PRAGMA foreign_keys=1

allora potrebbe addirittura accadere che tutti i vincoli Primary/Foreign
Key possano venire allegramente violati senza nessuna conseguenza.
e naturalmente, in caso di mancata attivazione, non funzionano neppure
le sequenze di eventi ON CASCADE ... insomma, le conseguenze potrebbero
anche avere un impatto fortemente negativo, anche peggiore di quello
dovuto a mancata attivazione del supporto ricursivo per i triggers.

ciao Sandro
_______________________________________________
Gfoss@lists.gfoss.it
http://lists.gfoss.it/cgi-bin/mailman/listinfo/gfoss
Questa e' una lista di discussione pubblica aperta a tutti.
I messaggi di questa lista non hanno relazione diretta con le posizioni
dell'Associazione GFOSS.it.
666 iscritti al 22.7.2013

_______________________________________________
Gfoss@lists.gfoss.it
http://lists.gfoss.it/cgi-bin/mailman/listinfo/gfoss
Questa e' una lista di discussione pubblica aperta a tutti.
I messaggi di questa lista non hanno relazione diretta con le posizioni
dell'Associazione GFOSS.it.
666 iscritti al 22.7.2013

--
Giovanni Allegri
http://about.me/giovanniallegri
Twitter: https://twitter.com/_giohappy_
blog: http://blog.spaziogis.it
GEO+ geomatica in Italia http://bit.ly/GEOplus

Quindi se io metto dei vincoli sulle foreign keys nel mio DB perché funzionino devo attivarle ad ogni singola connessione ? Mi sembra un comportamento un po’ strano ?

···

Il giorno 21 febbraio 2014 10:16, G. Allegri <giohappy@gmail.com> ha scritto:

Il giorno 21 febbraio 2014 10:08, Luca Lanteri <mescal72@gmail.com> ha scritto:

Mi inserisco nella discussione per chiedere una cosa veramente banale.
Una volta attivati i recursive trigger e le foreign_keys su un database, questi rimangono attivi per quel determinato DB e solo per quello, o devo riattivarli ad ogni nuova connessione, o ancora peggio rimangono attivati su tutti i DB ?

Le PRAGMA sono attive per singola connessione (ed eventualmente con effetti retroattivi secondo le regole più specifiche della singola PRAGMA).
http://www.sqlite.org/pragma.html

giovanni


Gfoss@lists.gfoss.it
http://lists.gfoss.it/cgi-bin/mailman/listinfo/gfoss
Questa e’ una lista di discussione pubblica aperta a tutti.
I messaggi di questa lista non hanno relazione diretta con le posizioni dell’Associazione GFOSS.it.
666 iscritti al 22.7.2013

Giovanni Allegri
http://about.me/giovanniallegri
Twitter: https://twitter.com/giohappy
blog: http://blog.spaziogis.it
GEO+ geomatica in Italia http://bit.ly/GEOplus

Immagino che il comportamento corretto sia il primo, ma giusto per sicurezza…
grazie

Il giorno 21 febbraio 2014 09:54, <a.furieri@lqt.it> ha scritto:

On Fri, 21 Feb 2014 09:23:49 +0100, Andrea Peri wrote:

Ho dato una lettura al documento che indicavi.

Riassumendo:
prima della sqlite 3.6.18 i trigger ricorsivi non erano supporti e
quindi vanno eviate versioni di sqlite cosi’ vecchie.

Nelle versioni successive, pero’ i trigger ricorsivi erano
disabilitati by-default, ppunto come dicevi te.
Quindi occorre sempre inserire una clausola

PRAGMA recurvive_triggers=1

Usando gli applicativi di spatialite:
CLI e Spatialite-GUI.
Questa clausola
recursive_triggers va settata comunque o è implicita ?

con tutte le versioni attuali (CLI/GUI) e’ sempre disabilitata
by default; ma per analogia con quanto gia’ implementato per
l’analoga “PRAGMA foreign_keys” presumo invece che sarebbe piu’
opportuno abilitarla implicitamente.

Detto questo.

se un disgraziato lavora su QGIS, editando un dataset tramite la
finestra degli attributi, oppure trmaite le form customized che ora
qgis consente, tale clausola “recursive_triggers=1” probabilmente è a
0 , ma come puo’ fare per garantirsi di settarla a 1 ?

vista l’architettura SQLite, gestire questo tipo di PRAGMA ricade
sotto la piena responsabilita’ del sw che attiva la connessione:
non c’e’ nessun modo per renderele permanenti.

il problema e’ abbastanza facile da affrontare per tutti i tools che
gestiscono le connessioni in modo centralizzato (p.es. il data-provider
di QGIS, oppure i tool spatialite); ma nel caso p.es. dei plug-in Python
ciascun singolo plug-in e’ ovviamente libero di comportarsi come meglio
crede, e non c’e’ nessuna possibilita’ di imporre dall’esterno un
set di comportamenti predefiniti.

Qui mi sorge un dubbio serio…

E forse comincio a capire perche’ a suo tempo ebbi dei problemi…

N.B.: ed a questo proposito a me inizia a sorgere anche un ulteriore
dubbio; con tutta la proliferazione di tools e di interfacce che
iniziano a circolare, siamo sempre sicuri che il supporto per i vincoli
relazionali venga attivato in tutti i casi ?

perche’ se da qualche parte c’e’ un tool che apre una connessione per
conto proprio al di fuori del data-provider (p.es. in Python) che non
cura di impostare correttamente questo parametro di connessione:

PRAGMA foreign_keys=1

allora potrebbe addirittura accadere che tutti i vincoli Primary/Foreign
Key possano venire allegramente violati senza nessuna conseguenza.
e naturalmente, in caso di mancata attivazione, non funzionano neppure
le sequenze di eventi ON CASCADE … insomma, le conseguenze potrebbero
anche avere un impatto fortemente negativo, anche peggiore di quello
dovuto a mancata attivazione del supporto ricursivo per i triggers.

ciao Sandro


Gfoss@lists.gfoss.it
http://lists.gfoss.it/cgi-bin/mailman/listinfo/gfoss
Questa e’ una lista di discussione pubblica aperta a tutti.
I messaggi di questa lista non hanno relazione diretta con le posizioni dell’Associazione GFOSS.it.
666 iscritti al 22.7.2013

On Fri, 21 Feb 2014 10:08:56 +0100, Luca Lanteri wrote:

Mi inserisco nella discussione per chiedere una cosa veramente banale.
Una volta attivati i recursive trigger e le foreign_keys su un
database, questi rimangono attivi per quel determinato DB e solo per
quello, o devo riattivarli ad ogni nuova connessione, o ancora peggio
rimangono attivati su tutti i DB ?

le PRAGMA sono attributi che vivono dentro ad un oggetto connessione:
non appena chiudi quella connessione tutti i settings PRAGMA svaniscono.

ovviamente, nel DB-file non rimane nessuna traccia permanente, e quindi
le PRAGMA vanno specificate tutte le volte che stabilisci una connessione.

di norma le uniche PRAGMA che lasciano conseguenze permanenti (perche'
vanno a toccare fisicamente la struttura del DB-file) sono quelle legate
al dimensionamento delle pagine (PRAGMA page_size)

ciao Sandro

On Fri, 21 Feb 2014 10:20:38 +0100, Luca Lanteri wrote:

Quindi se io metto dei vincoli sulle foreign keys nel mio DB perché
funzionino devo attivarle ad ogni singola connessione ? Mi sembra un
comportamento un po' strano ?

Luca,

se ci pensi bene non e' affatto strano, anzi e' robustamente
consistente.

non ti dimenticare mai che SQLite non ha un'architettura client-server;
a tutti gli effetti e' la connessione stessa che funge da server.

di norma su qualsiasi DBMS client-server questo tipo di impostazioni
le fissi nei parametri di lancio del server, oppure in qualche
config-file particolare.

nel caso di SQLite invece le devi eventualmente specificare immediatamente
dopo avere stabilito la connessione e subito prima di andare ad eseguire
qualsiasi statement SQL.
BTW SQLite ha anche un'architettura completamente configuration-less
e platform-agnostic; e quindi aggiustare liberamente i dettagli fini
della configurazione non puo' che ricadere per intero sotto la piena
responsabilita' del singolo processo.

insomma, detta in altri termini: SQLite offre il 90% delle prestazioni
di PostgreSQL a fronte di una complessita' interna del 10%
ma tutta questa semplicita' e leggerezza ovviamente implica che un sacco
di attivita' di gestione che normalmente sono a carico del server sotto
SQLite passano invece sotto la completa responsabilita' dei singoli
processi client.

ciao Sandro

Ok, allora però sarebbe auspicabile che i vincoli tipo foreign key fossero sempre attivi, perché se faccio un DB da fornire ad altre persone e gli metto dei vincoli che poi non funzionano a cosa servono ?

ma forse mi sto perdendo qualcosa perché provando con i miei DB dove ho attivato delle FK tra tabelle, queste sembrano rimanere attive sempre.

···

Il giorno 21 febbraio 2014 10:25, <a.furieri@lqt.it> ha scritto:

On Fri, 21 Feb 2014 10:08:56 +0100, Luca Lanteri wrote:

Mi inserisco nella discussione per chiedere una cosa veramente banale.
Una volta attivati i recursive trigger e le foreign_keys su un
database, questi rimangono attivi per quel determinato DB e solo per
quello, o devo riattivarli ad ogni nuova connessione, o ancora peggio
rimangono attivati su tutti i DB ?

le PRAGMA sono attributi che vivono dentro ad un oggetto connessione:
non appena chiudi quella connessione tutti i settings PRAGMA svaniscono.

ovviamente, nel DB-file non rimane nessuna traccia permanente, e quindi
le PRAGMA vanno specificate tutte le volte che stabilisci una connessione.

di norma le uniche PRAGMA che lasciano conseguenze permanenti (perche’
vanno a toccare fisicamente la struttura del DB-file) sono quelle legate
al dimensionamento delle pagine (PRAGMA page_size)

ciao Sandro

E’ nella filosofia di SQLite essere permissiva di default. Pensa ad esempio alla tipizzazione leggerissima dei campi di una tabella.
Rinforzare i vincoli è un optin per l’utente.

Giovanni

···

Il giorno 21 febbraio 2014 10:41, Luca Lanteri <mescal72@gmail.com> ha scritto:

Ok, allora però sarebbe auspicabile che i vincoli tipo foreign key fossero sempre attivi, perché se faccio un DB da fornire ad altre persone e gli metto dei vincoli che poi non funzionano a cosa servono ?

ma forse mi sto perdendo qualcosa perché provando con i miei DB dove ho attivato delle FK tra tabelle, queste sembrano rimanere attive sempre.

L<


Gfoss@lists.gfoss.it
http://lists.gfoss.it/cgi-bin/mailman/listinfo/gfoss
Questa e’ una lista di discussione pubblica aperta a tutti.
I messaggi di questa lista non hanno relazione diretta con le posizioni dell’Associazione GFOSS.it.
666 iscritti al 22.7.2013

Giovanni Allegri
http://about.me/giovanniallegri
Twitter: https://twitter.com/giohappy
blog: http://blog.spaziogis.it
GEO+ geomatica in Italia http://bit.ly/GEOplus

Il giorno 21 febbraio 2014 10:25, <a.furieri@lqt.it> ha scritto:

On Fri, 21 Feb 2014 10:08:56 +0100, Luca Lanteri wrote:

Mi inserisco nella discussione per chiedere una cosa veramente banale.
Una volta attivati i recursive trigger e le foreign_keys su un
database, questi rimangono attivi per quel determinato DB e solo per
quello, o devo riattivarli ad ogni nuova connessione, o ancora peggio
rimangono attivati su tutti i DB ?

le PRAGMA sono attributi che vivono dentro ad un oggetto connessione:
non appena chiudi quella connessione tutti i settings PRAGMA svaniscono.

ovviamente, nel DB-file non rimane nessuna traccia permanente, e quindi
le PRAGMA vanno specificate tutte le volte che stabilisci una connessione.

di norma le uniche PRAGMA che lasciano conseguenze permanenti (perche’
vanno a toccare fisicamente la struttura del DB-file) sono quelle legate
al dimensionamento delle pagine (PRAGMA page_size)

ciao Sandro

questo è una scelta che in futuro probabilmnte modificheranno.

Infatti.
Quando fu’ introdotto il vincolo FK,

a gio vi ernao parecchi clients che essendo vecchiottelli non lo avrebbero supportato.

A quel punto per evitare problemi di compatibilita’.
Scelsero di metterla di default disattivata, permettendo a chi voleva usarla di attivarla con la pragma gia’ detta.

Nella pagina indicata da Furieri sta scritto che in futuro probabilmetne invertiranno la regola sara di defualt attivata, e con un pragma apposito sara’ possibile disattivarla.

Credo che gia’ nelle ultime versioni sia cosi’…

Ma su questo non sono sicurissimo.

A.

···

Il giorno 21 febbraio 2014 10:41, Luca Lanteri <mescal72@gmail.com> ha scritto:

Ok, allora però sarebbe auspicabile che i vincoli tipo foreign key fossero sempre attivi, perché se faccio un DB da fornire ad altre persone e gli metto dei vincoli che poi non funzionano a cosa servono ?

ma forse mi sto perdendo qualcosa perché provando con i miei DB dove ho attivato delle FK tra tabelle, queste sembrano rimanere attive sempre.

L<

Andrea Peri
. . . . . . . . .
qwerty àèìòù

Il giorno 21 febbraio 2014 10:25, <a.furieri@lqt.it> ha scritto:

On Fri, 21 Feb 2014 10:08:56 +0100, Luca Lanteri wrote:

Mi inserisco nella discussione per chiedere una cosa veramente banale.
Una volta attivati i recursive trigger e le foreign_keys su un
database, questi rimangono attivi per quel determinato DB e solo per
quello, o devo riattivarli ad ogni nuova connessione, o ancora peggio
rimangono attivati su tutti i DB ?

le PRAGMA sono attributi che vivono dentro ad un oggetto connessione:
non appena chiudi quella connessione tutti i settings PRAGMA svaniscono.

ovviamente, nel DB-file non rimane nessuna traccia permanente, e quindi
le PRAGMA vanno specificate tutte le volte che stabilisci una connessione.

di norma le uniche PRAGMA che lasciano conseguenze permanenti (perche’
vanno a toccare fisicamente la struttura del DB-file) sono quelle legate
al dimensionamento delle pagine (PRAGMA page_size)

ciao Sandro

On Thu, 20 Feb 2014 22:09:42 +0100, Andrea Peri wrote:

Infatti anche io credo che sia un problema di triggers.

"mistero nisterioso" completamente svelato.
*** leggete con attenzione le note finali in fondo ***

cominciamo mettendo in piedi un piccolo banale test:

CREATE TABLE test (id INTEGER PRIMARY KEY AUTOINCREMENT);
SELECT AddGeometryColumn('test', 'geom3003', 3003, 'POINT', 'XY');
SELECT CreateSpatialIndex('test', 'geom3003');
SELECT AddGeometryColumn('test', 'geom4326', 4326, 'POINT', 'XY');
SELECT CreateSpatialIndex('test', 'geom4326');

DROP TRIGGER gii_test_geom3003;

CREATE TRIGGER ins_geom4326 AFTER INSERT ON test
FOR EACH ROW BEGIN
UPDATE test SET geom3003 = ST_Transform(NEW.geom4326, 3003)
   WHERE rowid = NEW.ROWID;
END;

CREATE TRIGGER upd_geom4326 AFTER UPDATE OF geom4326 ON test
FOR EACH ROW BEGIN
UPDATE test SET geom3003 = ST_Transform(NEW.geom4326, 3003)
   WHERE rowid = NEW.ROWID;
END;

INSERT INTO test (id, geom4326) VALUES (NULL, MakePoint(42.11, 11.41, 4326));
INSERT INTO test (id, geom4326) VALUES (NULL, MakePoint(42.12, 11.42, 4326));
INSERT INTO test (id, geom4326) VALUES (NULL, MakePoint(42.13, 11.43, 4326));
INSERT INTO test (id, geom4326) VALUES (NULL, MakePoint(42.14, 11.44, 4326));
INSERT INTO test (id, geom4326) VALUES (NULL, MakePoint(42.15, 11.45, 4326));

UPDATE test SET geom4326 = MakePoint(42.25, 10.45, 4326) WHERE id = 1;
UPDATE test SET geom4326 = MakePoint(42.26, 10.46, 4326) WHERE id = 3;
UPDATE test SET geom4326 = MakePoint(42.27, 10.47, 4326) WHERE id = 5;

SELECT CheckSpatialIndex('test', 'geom4326');
SELECT CheckSpatialIndex('test', 'geom3003');

SELECT id, ST_X(geom4326), ST_Y(geom4326), ST_X(geom3003), ST_Y(geom3003)
FROM test;
SELECT * FROM idx_test_geom4326;
SELECT * FROM idx_test_geom3003;

micro-spiegazione:
- creaiamo una tavola che ha solo la Primary Key
- aggiungiamo una geometria POINT srid=4326 con SpatialIndex
- aggiungiamo una seconda geometria POINT srid=3003
   (sempre con SpatialIndex)
- definiamo una coppia di triggers per assicurare che tutte le
   volte che si inserisce una geometria WGS84 venga immediatamente
   aggiornata anche la corrispondente GaussBoaga
- inseriamo e modifichiamo qualche riga
- ed alla fine andiamo a verificare se entrambi gli Spatial Index
   sono validi oppure se presentano problemi di out-of-sync.

******* NOTE FINALI ***********

scritto cosi' funziona perfettamente.
anche senza attivare "PRAGMA recursive_triggers=1".

in effetti, anche da un punto di vista del purismo lessicale, non stiamo
utilizzando nessun trigger ricursivo (che cioe' richiama se stesso piu'
e piu' volte).
questi sono tutti banali triggers nidificati (un trigger che ne chiama
un altro and so on, ma senza mai tornare su se stesso)

il silver bullet che fa la differenza e che evita la corruzione degli
Spatial Index e' semplicemente questo qua:

DROP TRIGGER gii_test_geom3003;

veloce analisi tecnica:
-----------------------
questo trigger (standard splite) salvaguarda tutte le INSERT per la colonna
"geom3003" (quella che invece noi lasciamo sempre NULL, dato che il valore
lo inserisce sempre l'altro trigger "ins_geom4326").
se lasciamo dentro questo trigger finisce che viene sempre eseguito per
ultimo nella catena nidificata; (verificato con una lunga e pallosa sessione
di debugging ad hoc: fidatevi).
ma a questo livello NEW.geom3003 vale sempre NULL (valore iniziale assegnato
esplicitamente dalla INSERT), e quindi il valore correttamente assegnato
precedentemente da "ins_geom4326" viene sovrascritto e finisce che comunque
qua ci trovremo un bel NULL, che finisce definitivamente nello Spatial Index

il problema non esiste invece per l'UPDATE, dato che non adremo mai ad
aggiornare direttamente la colonna "geom3003" (verra' sempre aggiornata
indirettamente via Trigger).

valutazione finale:
-------------------
i triggers di SQLite certamente consentono di implementare "effetti speciali"
assolutamente favolosi.
ma e' un po' come scalare ad alta quota un'altissima parete rocciosa verticale;
ci si muove in zona ad altissimo rischio, il minimo errore e la piu' microscopica
disattenzione saranno certamente fatali :smiley:

ciao Sandro