Sphinx extension for Data Dictionary and Database Diagram.
The syntax is using extended Swagger format.
Database diagram will be generated by GraphViz. Because its dependency to GraphViz, please remember to properly setup GraphViz extension first.
> pip install sphinxcontrib-dd
Setup extension in conf.py
file.
extensions = ['sphinxcontrib.dd']
- definitions
- tables
- relationships
This is definitions as specified by Swagger here.
Example:
definitions: Identity: type: integer format: int64 minimum: 1 User: properties: id: $ref: '#/definitions/Identity' name: type: nvarchar maxLength: 255 Role: properties: id: $ref: '#/definitions/Identity' name: type: nvarchar maxLength: 255 UserRole: properties: id: $ref: '#/definitions/Identity' user_id: $ref: '#/definitions/Identity' role_id: $ref: '#/definitions/Identity'
Field Name | Description |
---|---|
name | Table name |
description | Information about the table |
columns | Should be simply $ref to definitions |
Example:
tables: User: name: users description: Table to stores user information. columns: $ref: '#/definitions/User' Role: name: roles description: Table to stores roles. columns: $ref: '#/definitions/Role' UserRole: name: users_roles description: Table to stores user roles. columns: $ref: '#/definitions/UserRole'
Determine the relationship between two entities.
Symbol | Meaning |
---|---|
| | One |
|| | One and only one |
|0 / 0| | Zero or one |
> / < | Many |
>0 / 0< | Zero or many |
>| / |< | One or many |
The syntax is <symbol>--<symbol>
.
Example:
relationships: - User ||--0< UserRole - UserRole >0--|| Role
This extension add two directives:
- .. database-diagram:: path [another_path]
- Embed database diagram produced by GraphViz.
- .. data-dictionary:: path [another_path]
- Embed data dictionary in table format.
- path
- Path to yml file.
- another_path
Optional path to another yml file.
If you already have a swagger spec file used to define your REST API, you can reuse that file as is without modification by specifying it here.
In the background I simply combine the two files into one.
This extension is inspired by sphinx_erdiagram.
But unfortunately, the extension has been heavily design for japanese language document. So it looks rather ugly in english document due to the font it use. And I also want to reuse the Swagger specification file used to define the REST API.
Example:
.. database-diagram:: example.yml
The example.yml
file from
here
will result in
this.
There are several options available to modify the look and feel of the diagram:
- graph-fontname
- Set font family for graph label. Default to "Times-Roman" inherited from GraphViz.
- graph-fontsize
- Point size or label. Default to 14 inherited from GraphViz.
- graph-label
- Label of the graph.
- graph-labeljust
Alignment of graph label. Default to "centered" inherited from GraphViz.
"l" and "r" for left- and right-justified labels, respectively.
- graph-labelloc
Location of graph label. Default to "top" inherited from GraphViz.
"t" and "b" for top- and bottom-justified labels, respectively.
- graph-margin
- Margin included in page, in inches. Default to 0.
- graph-nodesep
- Separation between nodes, in inches. Default to 0.75 inch.
- graph-ranksep
- Separation between ranks, in inches. Default to 0.75 inch.
- node-fontname
- Set font family for graph label. Default to "Times-Roman" inherited from GraphViz.
- node-fontsize
- Point size or label. Default to 14 inherited from GraphViz.
- node-shape
The shape of the node. Default to "box".
More here.
- node-style
Style of of the node. Default to "rounded"
More here.
- root-samerank
This option tells GraphViz that some node should be in the same rank.
This options is in comma separated value format.
Before everything else, please remember that:
- Rank direction is from left to right.
- The placement of the nodes is heavily influence by how you define the relationship.
- To completely understand this options, you must understand how GraphViz's DiGraph works.
Example:
Relationship
A ||--0< B
will produce:+---+ +---+ | A | ||----0< | B | +---+ +---+
If you understand dot syntax, the relationship above is translated into
A -> B
.While relationship
B >0--|| A
will produce:+---+ +---+ | B | >0----|| | A | +---+ +---+
Remember that rank direction is from left to right.
But for relationship
A ||--0< B
withroot-samerank
option in the directive like this:.. database-diagram:: external.yml :root-samerank: A B
It will forced the nodes to be in the same rank:
+---+ | A | +---+ = | | 0 ^ +---+ | B | +---+
To illustrate how the option works in comma separated value, imagine you have relationship in yaml file like this:
relationships: - A ||--0< B - B >0--|| C - C ||--0< D
Without
root-samerank
option, the nodes will be placed right next to each other resulting in one row. But if you set the option like this:.. database-diagram:: external.yml :root-samerank: A B, C D
It will produces diagram like this:
+---+ | A | +---+ = | | 0 ^ +---+ +---+ | B | >0----|| | C | +---+ +---+ = | | 0 ^ +---+ | D | +---+
Let's see how this works.
First remember that this option is in comma separated value format. This means that the option will produce to values:
A B
andC D
.These two values force A and B to be in the same rank and C and D to be in the same rank too. But because we didn't specify B and C to be in the same rank, C node is placed in the right of the B node.
If you want D node placed at the top of C node, you can simply change the relationship into
D >0--|| C
.
Now, if you understand dot language you may already realized that graph-*
and node-*
options is just a shameless rip-off from GrahpViz attribute.
That's completely correct.
I'm too lazy to define my own options and conversions.
Beside I strongly believe that we should not reinvent the wheel,
unless absolutely necessary.
I even too lazy to define all the attributes asides from the one I need.
So please let me know if you need a currently unavailable attributes.
Or simply ask a pull request.
But please remember that some attributes may unavailable for modification.
Complete options is available here. But you may find the pdf version is easier to read, though the html version is more comprehensive.
If you prefer the pdf version you can download it here. The options for node is available in appendixes A, edge in appendixes B and graph in appendixes C.
The options can also be set as config specified in conf.py
by prefixing it
with database_diagram_
and change the -
into _
character.
The value in conf.py
is applied to all directives but will be override by
options in the directive.
For example you want to set node-fontname
to "Calibri" for all diagram.
In conf.py
:
database_diagram_node_fontname = "Calibri"
You may set all the config value as string even for numeric value.
Please note that this options is not available as config:
- root-samerank
Note
To change the image format you should directly change GraphViz options.
graphviz_output_format = 'svg'
I want to change this to database_diagram_output_format
but for now I
just didn't know how to do that.
If you knows how to do that,
please let me know or add a pull request.
Generate data dictionary:
.. data-dictionary:: example.yml
Available options:
- widths
Space- or comma-separated list of integer. These values calculated into percent totaled to 100%.
The default is
1 1 1 4
that will be calculated into 14%, 14%, 14% and 57% respectively.- headers
Space- or comma-separated list of string that will become table header.
The default is
Name Type Length Description
.Note
If you want a column name that contains space, use comma-separated format instead.
- columns
Space- or comma-separated list attributes of a property.
The default is
name type maxLength description
.name
is a special keyword that points to the property name.
The options can also be set as config specified in conf.py
by prefixing it
with data_dictionary_
.
But set the value as list.
The value in conf.py
is applied to all directives but will be override by
options in the directive.
In conf.py
:
data_dictionary_widths = [1, 1, 1, 4] data_dictionary_headers = ['Name', 'Type', 'Length', 'Description'] data_dictionary_columns = ['name', 'type', 'maxLength', 'description']
- Fix allOf bug.
- Change
sphinx.util.compat.Directive
todocutils.parsers.rst.Directive
because it will be removed in Sphinx 1.7.
- Change table name in data dictionary into section.
- Resolve allOff.
- Change syntax for description from reStructuredText to Markdown because Swagger use Markdown.
- Description may contains reStructuredText syntax.
- Strange thing happens. After delete and re-upload version 0.1.0, pip is unable to install it.
- First public release.
- Change output format from
graphviz_output_format = 'svg'
todatabase_diagram_output_format = 'svg'
so it's only affect database-diagram directive.