Suite

Problème avec la couche de vue PostgreSQL dans QGIS

Problème avec la couche de vue PostgreSQL dans QGIS


J'ai une table PostgreSQL et la vue :

CREATE TABLE lines ( geom geometry (MultiLineString, 4326), type character variant (254), login text, gid serial NOT NULL, CONSTRAINT lines_pkey PRIMARY KEY (gid)) CREATE OR REPLACE VIEW lines_view AS SELECT lines.geom, lines.type, lines.gid FROM lignes; CRÉER OU REMPLACER LA RÈGLE add AS ON INSERT TO lines_view DO INSTEAD INSERT INTO in lines (geom, type, login) VALUES (new.geom, new.type, "current_user"()); CRÉER OU REMPLACER LA RÈGLE del AS ON DELETE TO lines_view DO INSTEAD DELETE FROM lines WHERE lines.login = "current_user"()::text AND lines.gid = old.gid; CRÉER OU REMPLACER LA RÈGLE upd AS ON UPDATE TO lines_view DO INSTEAD UPDATE lines SET geom = new.geom, type = new.type, login = "current_user"() WHERE lines.login = "current_user"()::text AND lines. gid = nouveau.gid;

Donc, le problème est que lorsque je charge cette lines_view dans QGIS en tant que couche et que j'ajoute des lignes, après l'enregistrement, je ne peux pas utiliser "l'outil de nœud" pour Nouveau lignes ("outil Nœud : n'a pas pu s'accrocher à un segment du calque courant"). Mais lorsque j'utilise l'outil de déplacement sur eux (sélectionnez simplement le bouton "déplacer la (les) fonctionnalité(s)" et cliquez sur Nouveau line) "l'outil de nœud" commence à fonctionner comme d'habitude. Quelqu'un peut il m'aider avec ça?


En supposant que la seule raison pour laquelle vous avez besoin de ces vues est de contrôler leconnexionvaleur de la colonne et qui peut mettre à jour quelles lignes, alors vous n'avez pas réellement besoin d'une vue ici.

Commencez par créer unINSÉRERdéclencheur pour toujours régler leconnexioncolonne:

CRÉER OU REMPLACER LA FONCTION set_login_to_current_user() RETOURNE LA LANGUE DE DÉCLENCHEMENT plpgsql AS $$ BEGIN NEW.login = current_user; RETOUR NEUF ; FIN $$ ; CREATE TRIGGER insert_on_lines AVANT L'INSERTION SUR les lignes POUR CHAQUE LIGNE EXECUTER LA PROCEDURE set_login_to_current_user() ;

(Notez que c'est un peu différent d'unDÉFAUTvaleur. UNEDÉFAUTne se déclencherait que si aucune valeur n'était fournie. Ce déclencheur remplace la valeur même si l'utilisateur a essayé d'en spécifier une.)

Ajoutez maintenant un déclencheur de mise à jour qui empêche la modification des lignes n'appartenant pas à l'utilisateur actuel :

CRÉER OU REMPLACER LA FONCTION prevent_update_for_other_user() RETOURNE LA LANGUE DE DÉCLENCHEMENT plpgsql AS $$ COMMENCER SI OLD.login != current_user ALORS RAISE EXCEPTION 'Tentative de modification de la ligne appartenant à un autre utilisateur'; ELSE NEW.login = current_user; RETOUR NEUF ; FIN SI; FIN $$ ; CREATE TRIGGER update_on_lines AVANT LA MISE A JOUR DES lignes POUR CHAQUE LIGNE EXECUTER PROCEDURE prevent_update_for_other_user() ;

Et enfin, ajoutez un déclencheur qui empêche la suppression :

CRÉER OU REMPLACER LA FONCTION prevent_delete_for_other_users() RETOURNE LA LANGUE DE DÉCLENCHEMENT plpgsql AS $$ COMMENCER SI OLD.login != current_user ALORS RAISE EXCEPTION 'Tentative de suppression d'une ligne appartenant à un autre utilisateur'; AUTRE RETOUR VIEUX; FIN SI; FIN $$ ; CREATE TRIGGER delete_on_lines AVANT DE SUPPRIMER DES lignes POUR CHAQUE LIGNE EXECUTER PROCEDURE prevent_delete_for_other_users() ;

J'ai testé que cela fonctionne correctement avec PostgreSQL 9.3/PostGIS 2.1.4 et QGIS 2.8.1, mais comme il n'utilise que les fonctionnalités de base de PostgreSQL, je m'attends à ce que cela fonctionne dans les versions supérieures de tout.

Notez que dans les cas de mise à jour et de suppression, je lève une erreur si un utilisateur essaie de modifier une ligne appartenant à un autre utilisateur. C'est légèrement différent de ce que vous avez posté, où vous ne faites rien en silence. Je ne le conseille pas. Lorsqu'il rejette silencieusement la commande, l'utilisateur peut penser que ses modifications ont été appliquées même si ce n'est pas le cas, et l'utilisateur peut être très confus lorsqu'il découvre plus tard que ses modifications sont « manquantes ». En signalant une erreur, l'utilisateur sait immédiatement qu'un changement qu'il a tenté a été rejeté et peut annuler les modifications en conséquence. Si tu vraiment devez continuer en silence, vous pouvez remplacer leAUGMENTERcommandes avec

RETOUR NULL ;

pour empêcher silencieusement la modification ou la suppression.

Je tiens également à noter que cela ne représente pas exactement la "sécurité" en soi, mais cela peut faire partie de la solution en combinaison avec d'autres choses. Vous devez combiner cela avec les autorisations appropriées pour empêcher les utilisateurs de modifier les déclencheurs ou les fonctions de déclencheur. Surtout, vous ne pouvez pas filtrer les lignes qu'un utilisateur particulier est en mesure de vue (mais votre question ne le fait pas de toute façon). Il convient également de noter que PG 9.5 aura une "sécurité au niveau des lignes" prête à l'emploi, ce qui serait un moyen encore meilleur de résoudre ce problème.


Vous n'avez pas mentionné la version de qgis ni de postgis, qgis 2.10 ne vous permet pas d'éditer une table sans clé primaire - ce qui serait le cas de votre vue.