Sphinx extension for Data Dictionary and Database Diagram
Project description
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.
Installation
> pip install sphinxcontrib-dd
Setup extension in conf.py file.
extensions = ['sphinxcontrib.dd']
Schema
definitions
tables
relationships
definitions
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'
tables
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'
relationships
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
Usage
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 split the spec.
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.
Database Diagram
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 with root-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 and C 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
Data Dictionary
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.
- 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']
TODO
Change table name in data dictionary into h+1 depending on the context.
Change output format from graphviz_output_format = 'svg' to database_diagram_output_format = 'svg' so it’s only affect database-diagram directive.