[QGIS-it-user] Qgis&Postgresql - Vista editabile con geometria

Buongiorno a tutti,
forse non è il posto giusto per esporre un simile quesito,
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!

Ciao a tutti,

Il problema è stato risolto grazie al prezioso intervento del sig. Marucci
F. nella mailing-list gfoss.
Non è un tema facile l'editing delle viste, per molti un tabù, ma neanche
impossibile.

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

I campi dinamici di calcolo vanno segnati con ''::text as nomecampo oppure
null::text as nomecampo.

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!

Ora avete un'intera demo funzionante applicabile in Postgresql con tanto di
vista editabile!
Basta cambiare massivamente i nomi dei campi per ottenere ciò che vi serve.
Enjoy!

-----
Falz
--
Sent from: http://osgeo-org.1560.x6.nabble.com/QGIS-Italian-User-f5250612.html

Condivido riportando una breve demo didattica per concludere 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;

-----
Falz
--
Sent from: http://osgeo-org.1560.x6.nabble.com/QGIS-Italian-User-f5250612.html