PostgreSQL La base de donnees la plus sophistiquee au monde.

Forums PostgreSQL.fr

Le forum officiel de la communauté francophone de PostgreSQL

Vous n'êtes pas identifié(e).

#1 23/04/2015 11:50:31

DarkHorse
Membre

Trigger vers Node.js

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

#2 23/04/2015 11:57:11

rjuju
Administrateur

Re : Trigger vers Node.js

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

Hors ligne

#3 23/04/2015 13:35:33

DarkHorse
Membre

Re : Trigger vers Node.js

Merci pour cette réponse rapide !

Le langage plperl? Je ne connais pas du tout, ça s'utilise comment dans PgAdminIII?

Hors ligne

#4 23/04/2015 13:45:02

rjuju
Administrateur

Re : Trigger vers Node.js

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

Hors ligne

#5 04/05/2015 14:44:34

DarkHorse
Membre

Re : Trigger vers Node.js

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

#6 04/05/2015 14:56:25

dverite
Membre

Re : Trigger vers Node.js

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)

Hors ligne

#7 04/05/2015 14:58:44

DarkHorse
Membre

Re : Trigger vers Node.js

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

#8 04/05/2015 15:05:34

dverite
Membre

Re : Trigger vers Node.js

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.

Hors ligne

#9 04/05/2015 15:14:56

DarkHorse
Membre

Re : Trigger vers Node.js

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

#10 04/05/2015 15:27:09

dverite
Membre

Re : Trigger vers Node.js

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.

Hors ligne

Pied de page des forums