Small script to generate pretty Graphviz graph of Entity Relationships

111 views
Skip to first unread message

RaulG

unread,
Nov 1, 2009, 1:44:40 AM11/1/09
to SQLElixir
Hi,

for anyone who is interested - here's a script I coded in a couple of
mins to generate a relationship diagram code out of any elixir
model.py module, using graphviz ( http://www.graphviz.org/ ). The
output of this script must be compiled with graphviz to generate the
pretty pictures. Rename model with your own Elixir model definition
python module.

import elixir, model, inspect
from model import *

classes = [m for m in model.__dict__.values() if inspect.isclass(m)
and issubclass(m, Entity) ]

print('digraph G {')

for c in classes:
manytoones = [f for f in c.__dict__.values() if f.__class__ ==
elixir.relationships.ManyToOne]
onetomanys = [f for f in c.__dict__.values() if f.__class__ ==
elixir.relationships.OneToMany]
onetoones = [f for f in c.__dict__.values() if f.__class__ ==
elixir.relationships.OneToOne]
manytomanys = [f for f in c.__dict__.values() if f.__class__ ==
elixir.relationships.ManyToMany]

for c2 in manytoones:
print('%s -> %s [headlabel="%s" taillabel="%s" label="%s"]'%
(c.__name__, c2.of_kind, '1', '*', c2.name))
for c2 in onetomanys:
print('%s -> %s [headlabel="%s" taillabel="%s" label="%s"]'%
(c.__name__, c2.of_kind, '*', '1', c2.name))
for c2 in onetoones:
print('%s -> %s [headlabel="%s" taillabel="%s" label="%s"]'%
(c.__name__, c2.of_kind, '1', '1', c2.name))
for c2 in manytomanys:
print('%s -> %s [headlabel="%s" taillabel="%s" label="%s"]'%
(c.__name__, c2.of_kind, '*', '*', c2.name))

print('}')

RaulG

unread,
Nov 1, 2009, 4:43:32 PM11/1/09
to SQLElixir
Update to make is look more UML-is:

#!/usr/bin/env python
import elixir, model, inspect
from model import *

classes = [m for m in model.__dict__.values() if inspect.isclass(m)
and issubclass(m, Entity) and m.__name__ != 'Entity' ]

print('digraph G {')
print('node [shape=plaintext]')
#print('edge [arrowsize=0.5 fontsize=9]')
print('edge [arrowsize=0.25 fontsize=11 fontcolor=blue]')

for c in classes:
manytoones = [f for f in c.__dict__.values() if f.__class__ ==
elixir.relationships.ManyToOne]
onetomanys = [f for f in c.__dict__.values() if f.__class__ ==
elixir.relationships.OneToMany]
onetoones = [f for f in c.__dict__.values() if f.__class__ ==
elixir.relationships.OneToOne]
manytomanys = [f for f in c.__dict__.values() if f.__class__ ==
elixir.relationships.ManyToMany]
fields = [f for f in c.__dict__.values() if f.__class__ ==
elixir.fields.Field]

fieldstr = '<tr><td align="left">' + '</td></tr><tr><td
align="left">'.join(["+%s(%s)"%(f.name, f.type.__name__) for f in
fields]) + "</td></tr>"
relstr = ''.join(['<tr><td align="left" port="%s">%s</td></tr>'%
(f.name, f.name) for f in manytoones + onetomanys + onetoones +
manytomanys])
if relstr == '':
relstr = '<tr><td></td></tr>'

print('%s [label=< \
<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0"
CELLPADDING="0"> \
<TR CELLBORDER="1" CELLSPACING="0" CELLPADDING="0"
border="1"><TD border="1" bgcolor="lightblue">%s</TD></TR> \
<TR><TD> <table BORDER="0" CELLBORDER="0" >%s</table> </
TD></TR> \
<TR><TD> <table BORDER="0" CELLBORDER="0" >%s</table> </
TD></TR> \
</TABLE>>]; \
'%(c.__name__, c.__name__, fieldstr, relstr))

for c2 in manytoones:
#print('%s -> %s [headlabel="%s" taillabel="%s" label="%s"]'%
(c.__name__, c2.of_kind, '1', '*', c2.name))
print('%s : %s -> %s [headlabel="%s" taillabel="%s"]'%
(c.__name__, c2.name , c2.of_kind, '1', '*'))

for c2 in onetomanys:
#print('%s -> %s [headlabel="%s" taillabel="%s" label="%s"]'%
(c.__name__, c2.of_kind, '*', '1', c2.name))
print('%s : %s -> %s [headlabel="%s" taillabel="%s"]'%
(c.__name__, c2.name , c2.of_kind, '*', '1'))
for c2 in onetoones:
#print('%s -> %s [headlabel="%s" taillabel="%s" label="%s"]'%
(c.__name__, c2.of_kind, '1', '1', c2.name))
print('%s : %s -> %s [headlabel="%s" taillabel="%s"]'%
(c.__name__, c2.name , c2.of_kind, '1', '1'))
for c2 in manytomanys:
#print('%s -> %s [headlabel="%s" taillabel="%s" label="%s"]'%
(c.__name__, c2.of_kind, '*', '*', c2.name))
print('%s : %s -> %s [headlabel="%s" taillabel="%s"]'%
(c.__name__, c2.name , c2.of_kind, '*', '*'))

print('}')

Andrew Jones

unread,
Nov 18, 2009, 4:44:59 PM11/18/09
to SQLElixir
Modified to handle class inheritance.

#!/usr/bin/env python
import elixir, model, inspect
from model import *

classes = [m for m in model.__dict__.values() if inspect.isclass(m)
and issubclass(m, Entity) and m.__name__ != 'Entity' ]

print('digraph G {')
print('node [shape=plaintext]')
#print('edge [arrowsize=0.5 fontsize=9]')
print('edge [arrowsize=0.25 fontsize=11 fontcolor=blue]')

for c in classes:

manytoones = [f for f in c.__dict__.values() if f.__class__ ==
elixir.relationships.ManyToOne]
onetomanys = [f for f in c.__dict__.values() if f.__class__ ==
elixir.relationships.OneToMany]
onetoones = [f for f in c.__dict__.values() if f.__class__ ==
elixir.relationships.OneToOne]
manytomanys = [f for f in c.__dict__.values() if f.__class__ ==
elixir.relationships.ManyToMany]
inheritsfrom = [bc for bc in c.__bases__ if bc != Entity]

fields = [f for f in c.__dict__.values() if f.__class__ ==
elixir.fields.Field]

fieldstr = '<tr><td align="left">' + '</td></tr><tr><td
align="left">'.join(["+%s"%(f.name) for f in fields]) + "</td></tr>"
for c2 in inheritsfrom:
print('%s -> %s [headlabel="%s" taillabel="%s"]' %
(c.__name__, c2.__name__, '1', '1'))
print('}')

Gaetan de Menten

unread,
Nov 19, 2009, 10:40:41 AM11/19/09
to sqle...@googlegroups.com
You guys might want to put this on a new page in the Wiki and add a
link to it on the Goodies page at:
http://elixir.ematia.de/trac/wiki/Goodies
> --
>
> You received this message because you are subscribed to the Google Groups "SQLElixir" group.
> To post to this group, send email to sqle...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/sqlelixir?hl=.
>
>
>



--
Gaëtan de Menten
http://openhex.org

Graham Higgins

unread,
Nov 20, 2009, 9:04:31 AM11/20/09
to sqle...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 19 Nov 2009, at 15:40, Gaetan de Menten wrote:

> You guys might want to put this on a new page in the Wiki and add a
> link to it on the Goodies page at:
> http://elixir.ematia.de/trac/wiki/Goodies


For info, I wrote up my initial foray at transcribing the script to a
Pylons controller action:

http://bel-epa.com/posts/elixir-dot-model.xml

s'pretty.

(Actually, not just pretty but pretty handy, too).

Cheers,

Graham

http://www.linkedin.com/in/ghiggins




-----BEGIN PGP SIGNATURE-----

iEYEARECAAYFAksGoe8ACgkQOsmLt1NhivygIgCbB/H/5LIysohjLIeshOi2H9CZ
T3wAoOEZQhhp7WEO61RJrxGXSdpFy1K3iQCVAgUBSwah71nrWVZ7aXD1AQIfbQP+
PdiRkVc3BsFWuNLXpE/ZP2Z9TDYxwEqR/ST87ClCrb8qU6eII3Q/uzOVu9HJ/uHJ
BW069JR55esIhxUPdXVFMmfsxcv/P6G4nhAnd+wpXCgoBCz+GBuPnA/zUihVRtCB
Ltugg45GwL3JZykqrKvUyQXbSBXvlBMMLox9grIZBKs=
=a3iR
-----END PGP SIGNATURE-----

Reply all
Reply to author
Forward
0 new messages