Re: Graphe de dépendances entre les objets d'une base
Le Wed, 28 Mar 2007 00:47:25 +0200,
Guillaume Lelarge <guillaume(at)lelarge(dot)info> a écrit :
> postgresql-autodoc est capable de générer un fichier de ce type...
> mais je n'ai jamais réussi à en faire quoi que ce soit.
Je connaissais pas cette application, ça à l'air assez intéressant.
Faudra que je regarde, mais les exemples sont pas beau :(
> J'avais écrit un petit script Ruby pour ça :
>
> http://blog.guillaume.lelarge.info/index.php/post/2007/01/24/Comment-creer-une-image-representant-les-tables-et-leur-relations-a-partir-dune-base-PostgreSQL
> et un exemple en jpg :
> http://blog.guillaume.lelarge.info/public/pgruined/pagila.jpg
>
> Ne convient que pour des petites bases, n'est pas vraiment terminé,
> est plutôt un hack rapide. A utiliser juste pour voir.
Ah, niquel, ça correspond à ce que je cherchais :D
J'ai du faire quelques modifs pour que ça marche, et
pour l'adapter à la base en question :
- modification de PGconn.open en PGconn.connect (avec les paramètres
qui vont bien), car open est une méthode privée (dans ma version de
la bibliothèque postgres pour ruby que j'ai, en tout cas
libpgsql-ruby1.8, version 0.7.1 (paquet Debian Sid))
- correction de la récupération des valeurs pour la première requête
(ça à l'air de retourner une liste, plutôt qu'un hash)
- modification des requêtes SQL pour n'avoir que les identifiants des
tables (a.attname like '%id'), et pas le nom des arcs (ça allège un peu
le graphe)
- on ajoute un noeud, uniquement si le label n'est pas nul : vu que je
filtrais les identifiants et que j'ai des tables sans identifiants, la
génération du XML plantait (impossible de concaténer nil + String)
Au cas où, je mets le diff en pièce jointe ...
> Pour infos, c'est une des propositions pour un projet SoC de pgAdmin
> III.
Ah, c'est cool, j'avais même pas vu que des projets Postgres
participaient au SoC :(
Merci beaucoup en tout cas !
- Jonathan
--- pgruined.rb 2007-03-28 01:40:34.000000000 +0200
+++ pgruined-jon.rb 2007-03-28 01:40:29.000000000 +0200
@@ -7,7 +7,8 @@
g = GraphViz::new( "G", "output" => "svg" )
# Ouverture de la connexion PostgreSQL
-conn = PGconn.open('host' => 'localhost', 'dbname' => 'pagila')
+conn = PGconn.connect('localhost', 5432, '', '', 'pagila', 'user', 'password')
# Récupération de la liste des tables avec leurs colonnes respectives
res = conn.exec("SELECT c.oid as reloid,
@@ -16,7 +17,7 @@
CASE c.relkind WHEN 'r' THEN 'table' WHEN 'v' THEN 'vue' WHEN 'i' THEN 'index' WHEN 'S' THEN 'sequence' WHEN 's' THEN 'special' END as type,
'{<'||c.relname||'> '||c.relname||'|'||(SELECT array_to_string(array(SELECT '<'||a.attname||'> '||a.attname
FROM pg_catalog.pg_attribute a
-WHERE a.attrelid = c.oid AND a.attnum > 0 AND NOT a.attisdropped
+WHERE a.attrelid = c.oid AND a.attnum > 0 AND NOT a.attisdropped AND a.attname like '%id%'
ORDER BY a.attnum), '|'))||'}' as graphviz_record
FROM pg_catalog.pg_class c
JOIN pg_catalog.pg_roles r ON r.oid = c.relowner
@@ -27,13 +28,13 @@
ORDER BY 1,2")
res.result.each{ |tuple|
- if tuple['type'] == 'table' then
- g.add_node( tuple['nom'], "label" => tuple['graphviz_record'], "shape" => "record")
+ if tuple[3] == 'table' and tuple[4] != nil then
+ g.add_node( tuple[2], "label" => tuple[4], "shape" => "record")
end
}
# Récupération de la liste des clés étrangères avec nom, table1:colonne1, table2:colonne2
-res = conn.exec("select conname,
+res = conn.exec("select '',
translate(substring(relname||':'||substring(pg_get_constraintdef(pg_constraint.oid, true) from 'FOREIGN KEY (.*)')
from 1
for position('\)' in relname||':'||substring(pg_get_constraintdef(pg_constraint.oid, true) from 'FOREIGN KEY (.*)'))),
Home |
Main Index |
Thread Index