Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[JUJU-553] Add tool to infer entity schemas and render a ER-like diagram using graphviz #13694

Merged
merged 2 commits into from Feb 4, 2022

Conversation

achilleasa
Copy link
Contributor

@achilleasa achilleasa commented Feb 2, 2022

This PR contributes a CLI tool that analyzes the set of structs defined in Juju's state package and attempts to generate an ER-like diagram to aid with the data modeling work which is part of the transition from mongo to sqlite.

The actual diagram looks more like a UML class diagram as the number of entities (tables) and attributes makes it more difficult for graphviz to figure out a suitable layout for the graph nodes.

The tool automatically normalizes both table and field names to the underscore-cased format that folks are more familiar with when working with SQL databases. In addition, the tool will attempt to cluster together tables that share a common name prefix.

Future work ideas/suggestions:

  • Infer relations between tables by analyzing the names of fields that serve as foreign keys (this can also yield a more accurate clustering result). Alternatively, the tool could be seeded with an external (JSON/YAML etc.) file to provide hints as to which tables should be grouped together.
  • The tool currently lists the Go type for each attribute. However, for attributes that are nested objects or collections of objects we could automatically generate auxiliary tables for storing them and also annotate the graph with edges that will help identify the relationships between fields.

QA steps

$ cd scripts/dqlite/cmd

# NOTE 1: use 'open' instead of xdg-open if running on OSX
# NOTE 2: you must use `fdp` as your layout engine to get nice, rectangular output for the graph!
$ go run infer_schema.go | fdp -o erd.svg -Tsvg && xdg-open erd.svg

Yields something like this:

erd

@achilleasa achilleasa changed the title Add tool to infer entity schemas and render a ER-like diagram using graphviz [JUJU-553] Add tool to infer entity schemas and render a ER-like diagram using graphviz Feb 2, 2022
Copy link
Contributor

@juanmanuel-tirado juanmanuel-tirado left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice
LGTM

The tool parses the contents of the state package and emits an ER-like
diagram in dot notation. The generated diagram can then be fed into
graphviz to render the diagram. For example:

  go run infer_schema.go | circo -o er.svg -Tsvg
Copy link
Member

@SimonRichardson SimonRichardson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we also expand nested types, for example:

graph {
charm [shape=record, label=<{<b>charm</b><br/>github.com/juju/juju/state/charm.go | doc_id (string) | url (*charm.URL) | charm_version (string) | life (Life) | pending_upload (bool) | placeholder (bool) | bundle_sha256 (string) | storage_path (string) | macaroon ([]byte) | meta (*charm.Meta) | config (*charm.Config) | manifest (*charm.Manifest) | actions (*charm.Actions) | metrics (*charm.Metrics) | lxdprofile (*LXDProfile)}>];
}

Can we expand "manifest (*charm.Manifest)"?

@achilleasa
Copy link
Contributor Author

achilleasa commented Feb 3, 2022

Can we also expand nested types, for example:

graph {
charm [shape=record, label=<{<b>charm</b><br/>github.com/juju/juju/state/charm.go | doc_id (string) | url (*charm.URL) | charm_version (string) | life (Life) | pending_upload (bool) | placeholder (bool) | bundle_sha256 (string) | storage_path (string) | macaroon ([]byte) | meta (*charm.Meta) | config (*charm.Config) | manifest (*charm.Manifest) | actions (*charm.Actions) | metrics (*charm.Metrics) | lxdprofile (*LXDProfile)}>];
}

Can we expand "manifest (*charm.Manifest)"?

See the future work/suggestion list. Ideally we would want to identify complex types and create aux tables from them. So in this example, we would have a manifests table and the charm would have a FK to the manifest ID. Not sure how much effort that would require though...

I will play around with this idea and see how far I get.

@achilleasa
Copy link
Contributor Author

$$merge$$

@achilleasa
Copy link
Contributor Author

$$merge$$ (CI was happy but branch merge policy prevented the merge)

@achilleasa
Copy link
Contributor Author

$$merge$$

1 similar comment
@achilleasa
Copy link
Contributor Author

$$merge$$

@jujubot jujubot merged commit 36a89d8 into juju:dqlite-scaffolding Feb 4, 2022
@achilleasa achilleasa deleted the infer-entity-schemas branch February 4, 2022 14:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants