Lovely title i know...
I already posted how to make pretty graphs from your sqlalchemy models, the following is a complete paster command using that code.
import os
import sys
from paste.script.command import Command, BadCommand
from paste.script.filemaker import FileOp
from paste.deploy import loadapp, appconfig
from paste.script.pluginlib import find_egg_info_dir
import pydot
def graph_meta(meta, filename="dbgraph.jpeg"):
d = pydot.Dot()
nodes = {}
for table in meta.tables.itervalues():
n = nodes[table.name] = pydot.Node(table.name)
d.add_node(n)
for table in meta.tables.itervalues():
for c in table.c:
for fk in c.foreign_keys:
e = pydot.Edge(nodes[table.name], nodes[fk.column.table.name],
label=fk.column.name)
d.add_edge(e)
d.write_jpeg(filename)
def can_import(name):
"""Attempt to __import__ the specified package/module, returning True when
succeeding, otherwise False"""
try:
__import__(name)
return True
except ImportError:
return False
class DBGraph(Command):
summary = 'create a graph of the model'
parser = Command.standard_parser(simulate=True)
parser.add_option('--output', '-o',
default="dbraph.jpg",
dest='output',
help="output graph to file (default: dbgraph.jpg)")
group_name = 'pylons'
def command(self):
if len(self.args) == 0:
# Assume the .ini file is ./development.ini
config_file = 'development.ini'
if not os.path.isfile(config_file):
raise BadCommand('%sError: CONFIG_FILE not found at: .%s%s\n'
'Please specify a CONFIG_FILE' % \
(self.parser.get_usage(), os.path.sep,
config_file))
else:
config_file = self.args.pop()
config_name = 'config:%s' % config_file
here_dir = os.getcwd()
locs = dict(__name__="pylons-admin")
wsgiapp = loadapp(config_name, relative_to=here_dir)
# Determine the package name from the .egg-info top_level.txt.
egg_info = find_egg_info_dir(here_dir)
f = open(os.path.join(egg_info, 'top_level.txt'))
packages = [l.strip() for l in f.readlines()
if l.strip() and not l.strip().startswith('#')]
f.close()
# Start the rest of our imports now that the app is loaded
found_base = False
for pkg_name in packages:
# Import all objects from the base module
base_module = pkg_name + '.lib.base'
found_base = can_import(base_module)
if not found_base:
# Minimal template
base_module = pkg_name + '.controllers'
found_base = can_import(base_module)
if found_base:
break
if not found_base:
raise ImportError("Could not import base module. Are you sure "
"this is a Pylons app?")
base = sys.modules[base_module]
base_public = [__name for __name in dir(base) if not \
__name.startswith('_') or __name == '_']
for name in base_public:
locs[name] = getattr(base, name)
locs.update(dict(wsgiapp=wsgiapp))
graph_meta(locs['model'].meta, self.options.output)
If you want to use this drop it in a file called "commands.py" inside you pylons app, add the following to your setup.py:
[paste.paster_command]
dbgraph = .commands:DBGraph
Then run "python setup.py egg_info" and youll be able to run the command.
If your all very good ill move this to a package and post the egg here... ;)