Vous n'êtes pas identifié(e).
Pages : 1
Bonjour à tous,
Je réalise actuellement un projet mettant en place un serveur Node.js et une base de données PostgreSQL.
Cependant il y a des choses que je n'arrive pas à réaliser:
Dans ma base de données j'ai une table qui contient une liste de capteurs (une centaine), une colonne correspond à la valeur (de type integer) qui a été relevé par le capteur. Cette valeur est mise à jour par une source externe.
Je souhaitais, lorsque une de ces valeurs change d'état (les valeurs évoluent en permanence), réaliser un trigger qui permet d'envoyer une notification à mon serveur Node.js de l'évènement. Idéalement, que PostgreSQL m'envoie la ligne complète du capteur (dont la valeur à changée) vers mon serveur Node.js.
Actuellement j'évalue les mises à jours des valeurs par polling, c'est à dire que mon serveur réalise des requêtes toutes les 500ms et ce n'est clairement pas la solution à retenir (c'est pour dépanner en attendant).
D'ailleurs dans cette table, j'ai également une colonne contenant des mots clés (de type text[]), cependant lorsque je souhaite filtrer en faisant un SELECT sur un des mots clés, cela ne fonctionne pas.
Avez vous des pistes à suivre?
Hors ligne
Bonjour,
Vous pouvez utiliser un trigger dans un langage comme plperl qui devrait permettre de faire ça facilement, voir http://docs.postgresql.fr/9.4/plperl-triggers.html
Julien.
https://rjuju.github.io/
Hors ligne
Merci pour cette réponse rapide !
Le langage plperl? Je ne connais pas du tout, ça s'utilise comment dans PgAdminIII?
Hors ligne
postgres supporte de nombreux langages procéduraux (plperl, plpython, plv8 ...). Il suffit de créer l'extension plperl sur la base applicative (sous réserve d'avoir installé les paquets nécessaires), et vous pouvez écrire vos fonctions/trigger avec ce langage. Je vous conseille de regarder la documentation de plperl : http://docs.postgresql.fr/9.4/plperl.html
Julien.
https://rjuju.github.io/
Hors ligne
Bon j'ai essayé de faire quelque chose avec plperl, déjà c'est toute une galère à installer ce bouzin.... Il n'arrive même pas à trouver le .dll alors qu'il se trouve dans le bon dossier et tout... Ca m'aide pas vraiment tout cette histoire....
Hors ligne
Personnellement je regarderai vers une solution du style:
1) Côté envoi: trigger en plpgsql qui NOTIFY avec les données qui vont bien en paramètre
CREATE FUNCTION trigger_notify() RETURNS trigger AS
$$ BEGIN
perform pg_notify('nom_evenement', row_to_json(NEW)::text);
return new;
END
$$ language plpgsql;
row_to_json() est dispo à partir de PG 9.2. On pourrait utiliser n'importe quoi d'autre qui transforme la ligne en texte mais JSON est le plus évident pour un récepteur en Javascript.
2) Côté réception avec Node.js mettre en oeuvre le LISTEN comme par exemple indiqué ici:
http://bjorngylling.com/2011-04-13/post … de-js.html
Dernière modification par dverite (04/05/2015 14:56:58)
@DanielVerite
http://blog-postgresql.verite.pro/
Hors ligne
Merci pour votre réponse, en effet j'ai suivi ce tutoriel (plusieurs fois même). Cependant lorsque je modifiais manuellement une valeur dans ma base de données, aucun événement n'était généré... Du moins, Node.js ne bronchais pas... Du coup la difficulté est de savoir où ça coince
Je viens d'écrire la fonction que vous aviez mis dans la console psql (dans pgadminIII), je valide avec un ";" à la fin comme il faut. Je m'attendais à voir une fonction apparaitre dans l'arborescence dans pgadminIII, mais que néni ! J'ai vraiment du mal à voir comment ça fonctionne
Dernière modification par DarkHorse (04/05/2015 15:05:35)
Hors ligne
Avec un LISTEN actif dans un terminal psql est-ce que ça reçoit la notification ou pas?
Le client en ligne de commande psql affiche les notifications avec des messages du style
Notification asynchrone « nom_evenement » reçue avec le contenu « truc » en provenance du
processus serveur de PID numéro.
Les notifications n'arrivent qu'après (et si) la transaction est COMMITée.
@DanielVerite
http://blog-postgresql.verite.pro/
Hors ligne
Ah ça y est je me retrouve un petit peu... Du moins j'ai retrouvé ma fonction ^^
Donc là si je résume, il y a une fonction trigger, qui, à part définir le nom de l'événement et le transformer en json, me semble pas servir à grand chose.
Ensuite je nomme une méthode dans Node.js du même nom que l'évènement défini dans la fonction trigger pour que celle-ci soit appelé lorsque l'événement a lieu. Jusque là c'est bon.
Mais où alors je rentre mes conditions qui définissent mon événement? (Changement d'une valeur dans la colonne "value" de la table "device")
Pour être honnête je me sens un peu perdu avec toutes ces fonctions et différentes modules, je suis un débutant en PostGreSQL et j'aurai aimé suivre une formation mais manque de fonds et de temps. On me demande dès le début des choses complexes.
Dernière modification par DarkHorse (04/05/2015 15:16:41)
Hors ligne
Il faut créer le trigger sur ce modèle
CREATE TRIGGER nomdutrigger
AFTER UPDATE OR INSERT
ON nomdelatable
FOR EACH ROW
EXECUTE PROCEDURE fonction_liee_au_trigger();
( à adapter)
La fonction proposée plus haut est aussi juste un modèle. S'il s'agit de conditionner le notify a un changement de valeur, un test de ce style fera l'affaire dans la fonction triggger en plpgsql (sinon depuis quelques versions de PG il est aussi possible de faire des conditions WHEN sur les colonnes dès la définition du trigger, voir la doc):
IF (NEW.nomcolonne IS DISTINCT FROM OLD.nomcolonne) THEN
perform pg_notify(etc..)
END IF;
L'avantage de IS DISTINCT FROM est qu'il gère bien les transition de ou vers NULL s'il s'avère que la colonne peut être à NULL.
@DanielVerite
http://blog-postgresql.verite.pro/
Hors ligne
Pages : 1