sqlalchemy_schemadisplay3.py
author Sandro Knauß <knauss@netzguerilla.net>
Thu, 27 Sep 2012 17:17:34 +0200
changeset 304 3b3410b70e85
parent 294 0e75bd39767d
permissions -rw-r--r--
Added tag v1.0a for changeset 9708742ff89c
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
294
0e75bd39767d adding LICENSE to all files
Sandro Knauß <knauss@netzguerilla.net>
parents: 77
diff changeset
     1
# Copyright (c) 2012 netzguerilla.net <iro@netzguerilla.net>
0e75bd39767d adding LICENSE to all files
Sandro Knauß <knauss@netzguerilla.net>
parents: 77
diff changeset
     2
# 
0e75bd39767d adding LICENSE to all files
Sandro Knauß <knauss@netzguerilla.net>
parents: 77
diff changeset
     3
# This file is part of Iro.
0e75bd39767d adding LICENSE to all files
Sandro Knauß <knauss@netzguerilla.net>
parents: 77
diff changeset
     4
# 
0e75bd39767d adding LICENSE to all files
Sandro Knauß <knauss@netzguerilla.net>
parents: 77
diff changeset
     5
# Permission is hereby granted, free of charge, to any person obtaining a copy of
0e75bd39767d adding LICENSE to all files
Sandro Knauß <knauss@netzguerilla.net>
parents: 77
diff changeset
     6
# this software and associated documentation files (the "Software"), to deal in
0e75bd39767d adding LICENSE to all files
Sandro Knauß <knauss@netzguerilla.net>
parents: 77
diff changeset
     7
# the Software without restriction, including without limitation the rights to use,
0e75bd39767d adding LICENSE to all files
Sandro Knauß <knauss@netzguerilla.net>
parents: 77
diff changeset
     8
# copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
0e75bd39767d adding LICENSE to all files
Sandro Knauß <knauss@netzguerilla.net>
parents: 77
diff changeset
     9
# #Software, and to permit persons to whom the Software is furnished to do so,
0e75bd39767d adding LICENSE to all files
Sandro Knauß <knauss@netzguerilla.net>
parents: 77
diff changeset
    10
# subject to the following conditions:
0e75bd39767d adding LICENSE to all files
Sandro Knauß <knauss@netzguerilla.net>
parents: 77
diff changeset
    11
# 
0e75bd39767d adding LICENSE to all files
Sandro Knauß <knauss@netzguerilla.net>
parents: 77
diff changeset
    12
# The above copyright notice and this permission notice shall be included in
0e75bd39767d adding LICENSE to all files
Sandro Knauß <knauss@netzguerilla.net>
parents: 77
diff changeset
    13
# all copies or substantial portions of the Software.
0e75bd39767d adding LICENSE to all files
Sandro Knauß <knauss@netzguerilla.net>
parents: 77
diff changeset
    14
# 
0e75bd39767d adding LICENSE to all files
Sandro Knauß <knauss@netzguerilla.net>
parents: 77
diff changeset
    15
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
0e75bd39767d adding LICENSE to all files
Sandro Knauß <knauss@netzguerilla.net>
parents: 77
diff changeset
    16
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
0e75bd39767d adding LICENSE to all files
Sandro Knauß <knauss@netzguerilla.net>
parents: 77
diff changeset
    17
# PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
0e75bd39767d adding LICENSE to all files
Sandro Knauß <knauss@netzguerilla.net>
parents: 77
diff changeset
    18
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
0e75bd39767d adding LICENSE to all files
Sandro Knauß <knauss@netzguerilla.net>
parents: 77
diff changeset
    19
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
0e75bd39767d adding LICENSE to all files
Sandro Knauß <knauss@netzguerilla.net>
parents: 77
diff changeset
    20
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
0e75bd39767d adding LICENSE to all files
Sandro Knauß <knauss@netzguerilla.net>
parents: 77
diff changeset
    21
77
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    22
# updated SQLA schema display to work with pydot 1.0.2
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    23
# download from: http://www.sqlalchemy.org/trac/wiki/UsageRecipes/SchemaDisplay
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    24
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    25
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    26
from sqlalchemy.orm.properties import PropertyLoader
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    27
import pydot
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    28
import types
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    29
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    30
__all__ = ['create_uml_graph', 'create_schema_graph', 'show_uml_graph', 'show_schema_graph']
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    31
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    32
def _mk_label(mapper, show_operations, show_attributes, show_datatypes, bordersize):
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    33
    html = '<<TABLE CELLSPACING="0" CELLPADDING="1" BORDER="0" CELLBORDER="%d" BALIGN="LEFT"><TR><TD><FONT POINT-SIZE="10">%s</FONT></TD></TR>' % (bordersize, mapper.class_.__name__)
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    34
    def format_col(col):
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    35
        colstr = '+%s' % (col.name)
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    36
        if show_datatypes:
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    37
            colstr += ' : %s' % (col.type.__class__.__name__)
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    38
        return colstr
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    39
            
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    40
    if show_attributes:
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    41
        html += '<TR><TD ALIGN="LEFT">%s</TD></TR>' % '<BR ALIGN="LEFT"/>'.join(format_col(col) for col in sorted(mapper.columns, key=lambda col:not col.primary_key))
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    42
    else:
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    43
        [format_col(col) for col in sorted(mapper.columns, key=lambda col:not col.primary_key)]
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    44
    if show_operations:
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    45
        html += '<TR><TD ALIGN="LEFT">%s</TD></TR>' % '<BR ALIGN="LEFT"/>'.join(
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    46
            '%s(%s)' % (name,", ".join(default is _mk_label and ("%s") % arg or ("%s=%s" % (arg,repr(default))) for default,arg in 
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    47
                zip((func.func_defaults and len(func.func_code.co_varnames)-1-(len(func.func_defaults) or 0) or func.func_code.co_argcount-1)*[_mk_label]+list(func.func_defaults or []), func.func_code.co_varnames[1:])
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    48
            ))
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    49
            for name,func in mapper.class_.__dict__.items() if isinstance(func, types.FunctionType) and func.__module__ == mapper.class_.__module__
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    50
        )
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    51
    html+= '</TABLE>>'
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    52
    return html
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    53
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    54
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    55
def create_uml_graph(mappers, show_operations=True, show_attributes=True, show_multiplicity_one=False, show_datatypes=True, linewidth=1.0, font="Bitstream-Vera Sans"):
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    56
    graph = pydot.Dot(prog='neato',mode="major",overlap="0", sep="0.01",dim="3", pack="True", ratio=".75")
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    57
    relations = set()
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    58
    for mapper in mappers:
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    59
        graph.add_node(pydot.Node(mapper.class_.__name__,
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    60
            shape="plaintext", label=_mk_label(mapper, show_operations, show_attributes, show_datatypes, linewidth),
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    61
            fontname=font, fontsize="8.0",
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    62
        ))
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    63
        if mapper.inherits:
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    64
            graph.add_edge(pydot.Edge(mapper.inherits.class_.__name__,mapper.class_.__name__,
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    65
                arrowhead='none',arrowtail='empty', style="setlinewidth(%s)" % linewidth, arrowsize=str(linewidth)))
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    66
        for loader in mapper.iterate_properties:
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    67
            if isinstance(loader, PropertyLoader) and loader.mapper in mappers:
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    68
                if hasattr(loader, 'reverse_property'):
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    69
                    relations.add(frozenset([loader, loader.reverse_property]))
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    70
                else:
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    71
                    relations.add(frozenset([loader]))
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    72
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    73
    for relation in relations:
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    74
        #if len(loaders) > 2:
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    75
        #    raise Exception("Warning: too many loaders for join %s" % join)
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    76
        args = {}
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    77
        def multiplicity_indicator(prop):
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    78
            if prop.uselist:
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    79
                return ' *'
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    80
            if any(col.nullable for col in prop.local_side):
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    81
                return ' 0..1'
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    82
            if show_multiplicity_one:
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    83
                return ' 1'
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    84
            return ''
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    85
        
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    86
        if len(relation) == 2:
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    87
            src, dest = relation
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    88
            from_name = src.parent.class_.__name__
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    89
            to_name = dest.parent.class_.__name__
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    90
            
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    91
            def calc_label(src,dest):
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    92
                return '+' + src.key + multiplicity_indicator(src)
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    93
            args['headlabel'] = calc_label(src,dest)
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    94
            
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    95
            args['taillabel'] = calc_label(dest,src)
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    96
            args['arrowtail'] = 'none'
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    97
            args['arrowhead'] = 'none'
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    98
            args['constraint'] = False
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
    99
        else:
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   100
            prop, = relation
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   101
            from_name = prop.parent.class_.__name__
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   102
            to_name = prop.mapper.class_.__name__
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   103
            args['headlabel'] = '+%s%s' % (prop.key, multiplicity_indicator(prop))
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   104
            args['arrowtail'] = 'none'
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   105
            args['arrowhead'] = 'vee'
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   106
        
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   107
        graph.add_edge(pydot.Edge(from_name,to_name,
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   108
            fontname=font, fontsize="7.0", style="setlinewidth(%s)"%linewidth, arrowsize=str(linewidth),
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   109
            **args)
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   110
        )
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   111
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   112
    return graph
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   113
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   114
#from sqlalchemy import Table, text
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   115
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   116
def _render_table_html(table, metadata, show_indexes, show_datatypes):
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   117
    def format_col_type(col):
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   118
        try:
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   119
            return col.type.get_col_spec()
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   120
        except NotImplementedError:
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   121
            return str(col.type)
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   122
        except AttributeError:
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   123
            return str(col.type)
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   124
    def format_col_str(col):
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   125
         if show_datatypes:
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   126
             return "- %s : %s" % (col.name, format_col_type(col))
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   127
         else:
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   128
             return "- %s" % col.name
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   129
    html = '<<TABLE BORDER="1" CELLBORDER="0" CELLSPACING="0"><TR><TD ALIGN="CENTER">%s</TD></TR><TR><TD BORDER="1" CELLPADDING="0"></TD></TR>' % table.name 
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   130
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   131
    html += ''.join('<TR><TD ALIGN="LEFT" PORT="%s">%s</TD></TR>' % (col.name, format_col_str(col)) for col in table.columns)
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   132
    html += '</TABLE>>'
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   133
    return html
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   134
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   135
def create_schema_graph(tables=None, metadata=None, show_indexes=True, show_datatypes=True, font="Bitstream-Vera Sans",
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   136
    concentrate=True, relation_options={}, rankdir='TB'):
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   137
    relation_kwargs = {
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   138
        'fontsize':"7.0"
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   139
    }
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   140
    relation_kwargs.update(relation_options)
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   141
    
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   142
    if not metadata and len(tables):
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   143
        metadata = tables[0].metadata
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   144
    elif not tables and metadata:
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   145
        if not len(metadata.tables):
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   146
            metadata.reflect()
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   147
        tables = metadata.tables.values()
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   148
    else:
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   149
        raise Exception("You need to specify at least tables or metadata")
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   150
    
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   151
    graph = pydot.Dot(prog="dot",mode="ipsep",overlap="ipsep",sep="0.01",concentrate=str(concentrate), rankdir=rankdir)
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   152
    for table in tables:
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   153
        graph.add_node(pydot.Node(str(table.name),
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   154
            shape="plaintext",
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   155
            label=_render_table_html(table, metadata, show_indexes, show_datatypes),
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   156
            fontname=font, fontsize="7.0"
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   157
        ))
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   158
    
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   159
    for table in tables:
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   160
        for fk in table.foreign_keys:
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   161
            edge = [table.name, fk.column.table.name]
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   162
            is_inheritance = fk.parent.primary_key and fk.column.primary_key
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   163
            if is_inheritance:
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   164
                edge = edge[::-1]
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   165
            graph_edge = pydot.Edge(
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   166
                headlabel="+ %s"%fk.column.name, taillabel='+ %s'%fk.parent.name,
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   167
                arrowhead=is_inheritance and 'none' or 'odot' ,
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   168
                arrowtail=(fk.parent.primary_key or fk.parent.unique) and 'empty' or 'crow' ,
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   169
                fontname=font, 
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   170
                #samehead=fk.column.name, sametail=fk.parent.name,
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   171
                *edge, **relation_kwargs
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   172
            )
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   173
            graph.add_edge(graph_edge)
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   174
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   175
# not sure what this part is for, doesn't work with pydot 1.0.2
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   176
#            graph_edge.parent_graph = graph.parent_graph
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   177
#            if table.name not in [e.get_source() for e in graph.get_edge_list()]:
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   178
#                graph.edge_src_list.append(table.name)
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   179
#            if fk.column.table.name not in graph.edge_dst_list:
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   180
#                graph.edge_dst_list.append(fk.column.table.name)
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   181
#            graph.sorted_graph_elements.append(graph_edge)
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   182
    return graph
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   183
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   184
def show_uml_graph(*args, **kwargs):
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   185
    from cStringIO import StringIO
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   186
    from PIL import Image
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   187
    iostream = StringIO(create_uml_graph(*args, **kwargs).create_png())
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   188
    Image.open(iostream).show(command=kwargs.get('command','gwenview'))
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   189
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   190
def show_schema_graph(*args, **kwargs):
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   191
    from cStringIO import StringIO
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   192
    from PIL import Image
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   193
    iostream = StringIO(create_schema_graph(*args, **kwargs).create_png())
7dce6c0f06fb adding database schema to documentation.
Sandro Knauß <knauss@netzguerilla.net>
parents:
diff changeset
   194
    Image.open(iostream).show(command=kwargs.get('command','gwenview'))