mercredi, janvier 24 2007

Comment créer une image représentant les tables et leur relations à partir d'une base PostgreSQL

et d'un script Ruby.

Tout a commencé quand toady (aka str, aka Sébastien Tricaud) a annoncé son nouveau projet, ruined. Cet outil écrit en Ruby analyse les règles iptables de votre serveur et crée une image graphique indiquant les interfaces, les protocoles et leurs relations. Dès que j'ai vu la copie d'écran, je me suis dit : punaise, c'est exactement ce que je veux faire avec une base PostgreSQL.

J'ai donc récupéré les sources de ruined, je les ai lu, je les ai compris (enfin, tout du moins, j'ai essayé, tout n'est pas encore très clair). Mais au moins, j'ai compris que le script passe par GraphViz pour générer le SVG et que la bibliothèque GraphViz pour Ruby dispose de deux instructions principales : add_node et add_edge. add_node permet d'ajouter un noeud au schéma, noeud qui sera représenté par un polygone (au choix, rectangle, losange, etc.). add_edge permet d'ajouter un lien entre deux noeuds, lien symbolisé par une flèche mono- ou bi-directionnelle. Donc, j'ai tout ce dont j'ai besoin : des boîtes pour représenter les tables, des flèches pour représenter les clés étrangères.

Je me suis donc mis à coder ça. Ne connaissant pas vraiment Ruby, je me suis basé sur le code de toady et sur la doc de Ruby. Pour éviter tout problème spécifique au langage, je me suis arrangé pour que les données renvoyées par PostgreSQL soient directement formatées comme je le souhaitais. En gros, le script exécute une première requête pour récupérer la liste des tables ainsi que les colonnes de chaque table. Puis, il exécute une deuxième requête qui se charge de récupérer les définitions des clés étrangères.

Voici le résultat (les trois fichiers en annexes à ce billet) :

Bon, comme vous le voyez, c'est chouette mais c'est loin d'être beau. Le texte qui aurait dû être dans les boîtes dépasse par moment, les flèches font parfois des détours surprenants. Cela étant dit, ça reste compréhensible et vu le travail que ça m'a demandé (trois heures), je n'ai pas vraiment à protester. De plus, ça ressemble beaucoup à ce que fait postgresql-autodoc, ce qui semble assez logique étant donné qu'il utilise lui-aussi un graphe dot.

Le pire arrive quand on essaie d'ouvrir le fichier SVG avec Inkscape. Les boites ne sont pas des entités mais un ensemble de lignes ?!?! Je ne comprends pas pourquoi GraphViz ne les a pas assemblé. Du coup, pour déplacer une table, on est contraint à sélectionner tous les traits et tous les labels... sauf que les flèches ne suivent pas la boîte ?!?!

Bon, ce n'est pas encore pour cette fois.