[Gfoss] Postgresql&Qgis - Vista editabile con geometria

Buongiorno a tutti,
sto cercando di creare una vista Postgresql con geometria di tipo punto in
modo da poterla editare direttamente in Qgis.
Il problema che non riesco a sbloccare è creare la RULE giusta per la fase
di INSERT, il famoso "RETURNING".
Condivido il codice demo per chi fosse interessato all'argomento:

--TABELLA FISICA "SITI"
create table myschema.siti
(
id serial primary key,
richiesto boolean,
nome character varying(100),
cod_ser character varying(70),
indirizzo character varying(100),
comune character varying(70),
determina_nr integer,
determina_data date,
scadenza_conc date,
voltura1_nr integer, --aggiungi
voltura1_data date, --aggiungi
voltura1_scadenza_conc date, --aggiungi
determina_nr_rinnovo integer,
determina_data_rinnovo date,
scadenza_conc_rinnovo date,
voltura2_nr integer, --aggiungi
voltura2_data date, --aggiungi
voltura2_scadenza_conc date, --aggiungi
note text,
cc integer,
num character varying(50),
classe integer,
verificato boolean,
foto boolean,
tratta character varying(50),
constraint siti_date_check check (determina_data < scadenza_conc and
determina_data_rinnovo < scadenza_conc_rinnovo and voltura1_data <
voltura1_scadenza_conc and voltura2_data < voltura2_scadenza_conc)
);
select AddGeometryColumn('myschema','siti','geom',3064,'POINT',2);
create index idx_siti_geom on myschema.siti using gist (geom);

--VISTA DEI SITI
create view myschema.vista as
select
id,
geom,
st_astext(st_transform(geom,25832)) as etrs89_coordinate,
richiesto,
--calcolo con le 4 date (scadenza_conc, voltura1_scadenza_conc,
scadenza_conc_rinnovo, voltura2_scadenza_conc)
(case
when --quando le date di scadenza sono superiori alla data odierna
((now() < voltura2_scadenza_conc) or (now() < scadenza_conc_rinnovo) or
(now() < voltura1_scadenza_conc) or (now() < scadenza_conc))
and --e mancano più di 180 giorni alla scadenza
((date_part('day', voltura2_scadenza_conc - now()) > 180)
or
(date_part('day', scadenza_conc_rinnovo - now()) > 180)
or
(date_part('day', voltura1_scadenza_conc - now()) > 180)
or
(date_part('day', scadenza_conc - now()) > 180)) then 'In vigore'::text
when --quando le date di scadenza sono state superate dalla data odierna
(now() > scadenza_conc)
and
(now() > voltura1_scadenza_conc or voltura1_scadenza_conc is null)
and
(now() > scadenza_conc_rinnovo or scadenza_conc_rinnovo is null)
and
(now() > voltura2_scadenza_conc or voltura2_scadenza_conc is null) then
'Scaduta'::text
when --quando mancano 180 giorni o meno alla scadenza
date_part('day', scadenza_conc - now()) <= 180
OR date_part('day', voltura1_scadenza_conc - now()) <= 180
OR date_part('day', scadenza_conc_rinnovo - now()) <= 180
OR date_part('day', voltura2_scadenza_conc - now()) <= 180 then 'In
scadenza'::text
else null end) as situazione,
determina_nr,
determina_data,
scadenza_conc,
voltura1_nr,
voltura1_data,
voltura1_scadenza_conc,
determina_nr_rinnovo,
determina_data_rinnovo,
scadenza_conc_rinnovo,
voltura2_nr,
voltura2_data,
voltura2_scadenza_conc,
tratta,
classe,
verificato,
foto,
cc,
num,
note,
indirizzo,
comune,
nome,
cod_ser,
st_astext(st_transform(geom,4326)) as wgs84_ddd
from myschema.siti;

--VISTA EDITABILE, REGOLE PER EDITING
--Delete
create or replace rule siti_cancella as
on delete to myschema.vista do instead
delete from myschema.siti where siti.id = old.id;

--Update
create or replace rule siti_modifica as
on update to myschema.vista do instead
update myschema.siti
set
richiesto = new.richiesto,
nome = new.nome,
cod_ser = new.cod_ser,
indirizzo = new.indirizzo,
comune = new.comune,
determina_nr = new.determina_nr,
determina_data = new.determina_data,
scadenza_conc = new.scadenza_conc,
voltura1_nr = new.voltura1_nr,
voltura1_data = new.voltura1_data,
voltura1_scadenza_conc = new.voltura1_scadenza_conc,
determina_nr_rinnovo = new.determina_nr_rinnovo,
determina_data_rinnovo = new.determina_data_rinnovo,
scadenza_conc_rinnovo = new.scadenza_conc_rinnovo,
voltura2_nr = new.voltura2_nr,
voltura2_data = new.voltura2_data,
voltura2_scadenza_conc = new.voltura2_scadenza_conc,
note = new.note,
cc = new.cc,
num = new.num,
classe = new.classe,
verificato = new.verificato,
foto = new.foto,
tratta = new.tratta,
geom = new.geom
where siti.id = new.id;

--Insert
create or replace rule siti_inserisci as
on insert to myschema.vista do instead
insert into myschema.siti
(id,
richiesto,
nome,
cod_ser,
indirizzo,
comune,
determina_nr,
determina_data,
scadenza_conc,
voltura1_nr,
voltura1_data,
voltura1_scadenza_conc,
determina_nr_rinnovo,
determina_data_rinnovo,
scadenza_conc_rinnovo,
voltura2_nr,
voltura2_data,
voltura2_scadenza_conc,
note,
cc,
num,
classe,
verificato,
foto,
tratta,
geom)
values
(nextval('myschema.siti_id_seq'::regclass),
new.richiesto,
new.nome,
new.cod_ser,
new.indirizzo,
new.comune,
new.determina_nr,
new.determina_data,
new.scadenza_conc,
new.voltura1_nr,
new.voltura1_data,
new.voltura1_scadenza_conc,
new.determina_nr_rinnovo,
new.determina_data_rinnovo,
new.scadenza_conc_rinnovo,
new.voltura2_nr,
new.voltura2_data,
new.voltura2_scadenza_conc,
new.note,
new.cc,
new.num,
new.classe,
new.verificato,
new.foto,
new.tratta,
st_force2d(new.geom))

returning
siti.id,
siti.richiesto,
siti.nome,
siti.cod_ser,
siti.indirizzo,
siti.comune,
siti.determina_nr,
siti.determina_data,
siti.scadenza_conc,
siti.voltura1_nr,
siti.voltura1_data,
siti.voltura1_scadenza_conc,
siti.determina_nr_rinnovo,
siti.determina_data_rinnovo,
siti.scadenza_conc_rinnovo,
siti.voltura2_nr,
siti.voltura2_data,
siti.voltura2_scadenza_conc,
siti.note,
siti.cc,
siti.num,
siti.classe,
siti.verificato,
siti.foto,
siti.tratta,
siti.geom
;
/*
ERROR: RETURNING list's entry 2 has different type from column "geom"
SQL state: 42P17
Detail: RETURNING list entry has type boolean, but column has type geometry.
LA COPPIA DI VOCI DELL'ELENCO DI RITORNO HA UN TIPO DIVERSO DALLA COLONNA
"GEOM"
*/

Ringraziando anticipatamente, si pongono distinti saluti!

--
Sent from: http://gfoss-geographic-free-and-open-source-software-italian-mailing.3056002.n2.nabble.com/

ciao,
i rule sono particolarmente sensibili, hanno bisogno che nel RETURNING ci
siano tutti i campi della tabella e che siano nello stesso ordine.
il mio consiglio quindi è quello di mantenere l'ordine dei campi anche
nella vista, e soprattutto nel RETURNING, nel quale dovrai anche aggiungere
i campi che hai aggiunto nella vista, ad esempio, nel tuo caso sarà:

drop view vista;

create view myschema.vista as
select
id,
richiesto,
nome,
cod_ser,
indirizzo,
comune,
determina_nr,
determina_data,
scadenza_conc,
voltura1_nr,
voltura1_data,
voltura1_scadenza_conc,
determina_nr_rinnovo,
determina_data_rinnovo,
scadenza_conc_rinnovo,
voltura2_nr,
voltura2_data,
voltura2_scadenza_conc,
note,
cc,
num,
classe,
verificato,
foto,
tratta,
geom,
st_astext(st_transform(geom,25832)) as etrs89_coordinate,
st_astext(st_transform(geom,4326)) as wgs84_ddd,
--calcolo con le 4 date (scadenza_conc,
voltura1_scadenza_conc,scadenza_conc_rinnovo, voltura2_scadenza_conc)
(case
when --quando le date di scadenza sono superiori alla data odierna
((now() < voltura2_scadenza_conc) or (now() < scadenza_conc_rinnovo) or
(now() < voltura1_scadenza_conc) or (now() < scadenza_conc))
and --e mancano più di 180 giorni alla scadenza
((date_part('day', voltura2_scadenza_conc - now()) > 180)
or
(date_part('day', scadenza_conc_rinnovo - now()) > 180)
or
(date_part('day', voltura1_scadenza_conc - now()) > 180)
or
(date_part('day', scadenza_conc - now()) > 180)) then 'In vigore'::text
when --quando le date di scadenza sono state superate dalla data odierna
(now() > scadenza_conc)
and
(now() > voltura1_scadenza_conc or voltura1_scadenza_conc is null)
and
(now() > scadenza_conc_rinnovo or scadenza_conc_rinnovo is null)
and
(now() > voltura2_scadenza_conc or voltura2_scadenza_conc is null) then
'Scaduta'::text
when --quando mancano 180 giorni o meno alla scadenza
date_part('day', scadenza_conc - now()) <= 180
OR date_part('day', voltura1_scadenza_conc - now()) <= 180
OR date_part('day', scadenza_conc_rinnovo - now()) <= 180
OR date_part('day', voltura2_scadenza_conc - now()) <= 180 then 'In
scadenza'::text
else null end) as situazione

from siti;

e il RULE INSERT sarà:

create or replace rule siti_inserisci as
on insert to myschema.vista do instead
insert into myschema.siti
(id,
richiesto,
nome,
cod_ser,
indirizzo,
comune,
determina_nr,
determina_data,
scadenza_conc,
voltura1_nr,
voltura1_data,
voltura1_scadenza_conc,
determina_nr_rinnovo,
determina_data_rinnovo,
scadenza_conc_rinnovo,
voltura2_nr,
voltura2_data,
voltura2_scadenza_conc,
note,
cc,
num,
classe,
verificato,
foto,
tratta,
geom)
values
(nextval('myschema.siti_id_seq'::regclass),
new.richiesto,
new.nome,
new.cod_ser,
new.indirizzo,
new.comune,
new.determina_nr,
new.determina_data,
new.scadenza_conc,
new.voltura1_nr,
new.voltura1_data,
new.voltura1_scadenza_conc,
new.determina_nr_rinnovo,
new.determina_data_rinnovo,
new.scadenza_conc_rinnovo,
new.voltura2_nr,
new.voltura2_data,
new.voltura2_scadenza_conc,
new.note,
new.cc,
new.num,
new.classe,
new.verificato,
new.foto,
new.tratta,
st_force2d(new.geom))

returning
siti.id,
siti.richiesto,
siti.nome,
siti.cod_ser,
siti.indirizzo,
siti.comune,
siti.determina_nr,
siti.determina_data,
siti.scadenza_conc,
siti.voltura1_nr,
siti.voltura1_data,
siti.voltura1_scadenza_conc,
siti.determina_nr_rinnovo,
siti.determina_data_rinnovo,
siti.scadenza_conc_rinnovo,
siti.voltura2_nr,
siti.voltura2_data,
siti.voltura2_scadenza_conc,
siti.note,
siti.cc,
siti.num,
siti.classe,
siti.verificato,
siti.foto,
siti.tratta,
siti.geom,
''::text as ETRS89_coordinate,
''::text as wgs84_ddd,
''::text as situazione
;

facci sapere.

saluti,
francesco

Il giorno lun 23 set 2019 alle ore 17:51 Falz <falcerisimone@inwind.it> ha
scritto:

Buongiorno a tutti,
sto cercando di creare una vista Postgresql con geometria di tipo punto in
modo da poterla editare direttamente in Qgis.
Il problema che non riesco a sbloccare è creare la RULE giusta per la fase
di INSERT, il famoso "RETURNING".
Condivido il codice demo per chi fosse interessato all'argomento:

--TABELLA FISICA "SITI"
create table myschema.siti
(
id serial primary key,
richiesto boolean,
nome character varying(100),
cod_ser character varying(70),
indirizzo character varying(100),
comune character varying(70),
determina_nr integer,
determina_data date,
scadenza_conc date,
voltura1_nr integer, --aggiungi
voltura1_data date, --aggiungi
voltura1_scadenza_conc date, --aggiungi
determina_nr_rinnovo integer,
determina_data_rinnovo date,
scadenza_conc_rinnovo date,
voltura2_nr integer, --aggiungi
voltura2_data date, --aggiungi
voltura2_scadenza_conc date, --aggiungi
note text,
cc integer,
num character varying(50),
classe integer,
verificato boolean,
foto boolean,
tratta character varying(50),
constraint siti_date_check check (determina_data < scadenza_conc and
determina_data_rinnovo < scadenza_conc_rinnovo and voltura1_data <
voltura1_scadenza_conc and voltura2_data < voltura2_scadenza_conc)
);
select AddGeometryColumn('myschema','siti','geom',3064,'POINT',2);
create index idx_siti_geom on myschema.siti using gist (geom);

--VISTA DEI SITI
create view myschema.vista as
select
id,
geom,
st_astext(st_transform(geom,25832)) as etrs89_coordinate,
richiesto,
--calcolo con le 4 date (scadenza_conc, voltura1_scadenza_conc,
scadenza_conc_rinnovo, voltura2_scadenza_conc)
(case
when --quando le date di scadenza sono superiori alla data odierna
((now() < voltura2_scadenza_conc) or (now() < scadenza_conc_rinnovo) or
(now() < voltura1_scadenza_conc) or (now() < scadenza_conc))
and --e mancano più di 180 giorni alla scadenza
((date_part('day', voltura2_scadenza_conc - now()) > 180)
or
(date_part('day', scadenza_conc_rinnovo - now()) > 180)
or
(date_part('day', voltura1_scadenza_conc - now()) > 180)
or
(date_part('day', scadenza_conc - now()) > 180)) then 'In vigore'::text
when --quando le date di scadenza sono state superate dalla data odierna
(now() > scadenza_conc)
and
(now() > voltura1_scadenza_conc or voltura1_scadenza_conc is null)
and
(now() > scadenza_conc_rinnovo or scadenza_conc_rinnovo is null)
and
(now() > voltura2_scadenza_conc or voltura2_scadenza_conc is null) then
'Scaduta'::text
when --quando mancano 180 giorni o meno alla scadenza
date_part('day', scadenza_conc - now()) <= 180
OR date_part('day', voltura1_scadenza_conc - now()) <= 180
OR date_part('day', scadenza_conc_rinnovo - now()) <= 180
OR date_part('day', voltura2_scadenza_conc - now()) <= 180 then 'In
scadenza'::text
else null end) as situazione,
determina_nr,
determina_data,
scadenza_conc,
voltura1_nr,
voltura1_data,
voltura1_scadenza_conc,
determina_nr_rinnovo,
determina_data_rinnovo,
scadenza_conc_rinnovo,
voltura2_nr,
voltura2_data,
voltura2_scadenza_conc,
tratta,
classe,
verificato,
foto,
cc,
num,
note,
indirizzo,
comune,
nome,
cod_ser,
st_astext(st_transform(geom,4326)) as wgs84_ddd
from myschema.siti;

--VISTA EDITABILE, REGOLE PER EDITING
--Delete
create or replace rule siti_cancella as
on delete to myschema.vista do instead
delete from myschema.siti where siti.id = old.id;

--Update
create or replace rule siti_modifica as
on update to myschema.vista do instead
update myschema.siti
set
richiesto = new.richiesto,
nome = new.nome,
cod_ser = new.cod_ser,
indirizzo = new.indirizzo,
comune = new.comune,
determina_nr = new.determina_nr,
determina_data = new.determina_data,
scadenza_conc = new.scadenza_conc,
voltura1_nr = new.voltura1_nr,
voltura1_data = new.voltura1_data,
voltura1_scadenza_conc = new.voltura1_scadenza_conc,
determina_nr_rinnovo = new.determina_nr_rinnovo,
determina_data_rinnovo = new.determina_data_rinnovo,
scadenza_conc_rinnovo = new.scadenza_conc_rinnovo,
voltura2_nr = new.voltura2_nr,
voltura2_data = new.voltura2_data,
voltura2_scadenza_conc = new.voltura2_scadenza_conc,
note = new.note,
cc = new.cc,
num = new.num,
classe = new.classe,
verificato = new.verificato,
foto = new.foto,
tratta = new.tratta,
geom = new.geom
where siti.id = new.id;

--Insert
create or replace rule siti_inserisci as
on insert to myschema.vista do instead
insert into myschema.siti
(id,
richiesto,
nome,
cod_ser,
indirizzo,
comune,
determina_nr,
determina_data,
scadenza_conc,
voltura1_nr,
voltura1_data,
voltura1_scadenza_conc,
determina_nr_rinnovo,
determina_data_rinnovo,
scadenza_conc_rinnovo,
voltura2_nr,
voltura2_data,
voltura2_scadenza_conc,
note,
cc,
num,
classe,
verificato,
foto,
tratta,
geom)
values
(nextval('myschema.siti_id_seq'::regclass),
new.richiesto,
new.nome,
new.cod_ser,
new.indirizzo,
new.comune,
new.determina_nr,
new.determina_data,
new.scadenza_conc,
new.voltura1_nr,
new.voltura1_data,
new.voltura1_scadenza_conc,
new.determina_nr_rinnovo,
new.determina_data_rinnovo,
new.scadenza_conc_rinnovo,
new.voltura2_nr,
new.voltura2_data,
new.voltura2_scadenza_conc,
new.note,
new.cc,
new.num,
new.classe,
new.verificato,
new.foto,
new.tratta,
st_force2d(new.geom))

returning
siti.id,
siti.richiesto,
siti.nome,
siti.cod_ser,
siti.indirizzo,
siti.comune,
siti.determina_nr,
siti.determina_data,
siti.scadenza_conc,
siti.voltura1_nr,
siti.voltura1_data,
siti.voltura1_scadenza_conc,
siti.determina_nr_rinnovo,
siti.determina_data_rinnovo,
siti.scadenza_conc_rinnovo,
siti.voltura2_nr,
siti.voltura2_data,
siti.voltura2_scadenza_conc,
siti.note,
siti.cc,
siti.num,
siti.classe,
siti.verificato,
siti.foto,
siti.tratta,
siti.geom
;
/*
ERROR: RETURNING list's entry 2 has different type from column "geom"
SQL state: 42P17
Detail: RETURNING list entry has type boolean, but column has type
geometry.
LA COPPIA DI VOCI DELL'ELENCO DI RITORNO HA UN TIPO DIVERSO DALLA COLONNA
"GEOM"
*/

Ringraziando anticipatamente, si pongono distinti saluti!

--
Sent from:
http://gfoss-geographic-free-and-open-source-software-italian-mailing.3056002.n2.nabble.com/
_______________________________________________
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.
764 iscritti al 23/08/2019

Ringrazio sentitamente il sig. Marucci per la preziosissima dritta in tema di
editing views.
In pratica, il concetto importante della RULE in fase di insert, è
rispettare l'ordine dei campi.

Nel RETURNING vanno listati i campi della tabella fisica, ordinati secondo
la disposizione dei campi della vista!

Nel mio caso, senza dover rifare la vista, ho riscritto ed applicato con
successo la fase finale:

returning --VANNO LISTATI I CAMPI DELLA TABELLA ORDINATI SECONDO LA VISTA!
siti.id,
siti.geom, --geometry
''::text as etrs89_ddd,
siti.richiesto, --boolean
''::text as situazione,
siti.determina_nr,
siti.determina_data,
siti.scadenza_conc,
siti.voltura1_nr,
siti.voltura1_data,
siti.voltura1_scadenza_conc,
siti.determina_nr_rinnovo,
siti.determina_data_rinnovo,
siti.scadenza_conc_rinnovo,
siti.voltura2_nr,
siti.voltura2_data,
siti.voltura2_scadenza_conc,
siti.tratta,
siti.classe,
siti.verificato,
siti.foto, --boolean
siti.cc,
siti.num,
siti.note,
siti.indirizzo,
siti.comune,
siti.nome,
siti.cod_ser,
''::text as wgs84_ddd
;
--ok!

Un grazie di cuore!!

--
Sent from: http://gfoss-geographic-free-and-open-source-software-italian-mailing.3056002.n2.nabble.com/

Condivido riportando una breve demo didattica per sintetizzare il discorso
delle viste editabili, da usare ad esempio in Qgis, il codice qui sotto può
essere copiato e incollato direttamente nella shell di Postgresql:

/*Places table*/
create table myschema.places
(id serial primary key,
nameplace character varying(100),
sectornumber integer);
select AddGeometryColumn('myschema','places','geom',3064,'POLYGON',2);

/*Site table*/
create table myschema.site
(id serial primary key,
verified boolean,
name character varying(100),
address character varying(100),
note text);
select AddGeometryColumn('myschema','site','geom',3064,'POINT',2);
create index idx_site_geom on myschema.site using gist (geom);

/*Myview view*/
create view myschema.myview as
select
id,
geom,
verified,
name,
address,
note,
(select p.nameplace from myschema.places p where
st_intersects(myschema.site.geom, p.geom)) as place,
(select p.sectornumber from myschema.places p where
st_intersects(myschema.site.geom, p.geom)) as sector,
st_astext(st_transform(geom,4326)) as wgs84_ddd
from myschema.site;

/*Rule for Deleting*/
create or replace rule site_delete as
on delete to myschema.myview do instead
delete from myschema.site where site.id = old.id;

/*Rule for Updating*/
create or replace rule site_update as
on update to myschema.myview do instead
update myschema.site
set
verified = new.verified,
name = new.name,
address = new.address,
note = new.note,
geom = new.geom
where site.id = new.id;

/*Rule for Inserting*/
create or replace rule site_insert as
on insert to myschema.myview do instead
insert into myschema.site (id, verified, name, address, note, geom)
values
(nextval('myschema.site_id_seq'::regclass), new.verified, new.name,
new.address, new.note, st_force2d(new.geom))
returning /*lista i campi della tabella ordinati secondo l'ordine della
vista*/
site.id,
site.geom,
site.verified,
site.name,
site.address,
site.note,
''::character varying(100) as place,
null::integer as sector,
''::text as wgs84_ddd;

--
Sent from: http://gfoss-geographic-free-and-open-source-software-italian-mailing.3056002.n2.nabble.com/