From your models to a diagram
Read this page in the documentation
From your models to a diagram The generators take plain options — a name, some fields, some associations. That is fine when you are drawing something by hand, but it means the picture of your schema is a second copy of the schema, and it goes stale the moment a column changes. The adapters read the real thing instead. Point one at a connection, a model class, a query result or a table description, and it produces the options a generator wants. That is the whole thing: every model registered on the connection, drawn, in one call. Which adapter You have | Use | Produces | --- | --- | --- | A connected Prorm | prormToER(prorm, opts?) | ERDiagramOptions | Model classes | modelsToER(models, opts?) | ERDiagramOptions | One model class | modelToDiagram(Model) | ModelDiagramOptions | Rows, or any objects | dataToDiagram(name, data) | ModelDiagramOptions | Named sets of rows | dataToER(collections, opts?) | ERDiagramOptions | describeTable() output | tableDescriptionToDiagram(name, desc) | ModelDiagramOptions | Several described tables | tableDescriptionsToER(tables, opts?) | ERDiagramOptions | From a connection prormToER() walks every registered model, reads its columns, keys and associations, and hands back ER options: exclude takes model names. Join tables and audit tables are the usual candidates — they add boxes without adding understanding. Note: the adapter reads what the model declares, so a column added straight to the database without a matching attribute will not appear. To draw what the database actually contains, go through describeTable() below. From one model Primary keys, unique columns, allowNull, defaults, auto-increment, enum values and field column names all carry across, as do the model's associations — hasMany, belongsTo, belongsToMany and their foreign keys, aliases and join tables. timestamps, paranoid and underscored come from the model's options, so the implicit createdAt / updatedAt / deletedAt columns are drawn when they exist. It works on a model that has been defined but not yet added, and on any object carrying the same statics — useful in tests, and for schemas that never became models. From data Sometimes there is no model: an API response, a CSV you just parsed, a collection from a store the ORM does not map. dataToDiagram() infers a shape from the values. Value | Inferred | --- | --- | 1, 42 | INTEGER | 1.5 | FLOAT | 10n | BIGINT | 'text' | STRING | true | BOOLEAN | new Date() | DATE | {…}, […] | JSON | Buffer | BLOB | null alone | UNKNOWN | Pass several rows when you have them. Columns are unioned across rows, and a column that is null in the first row can still be typed from a later one — one row gives you one row's worth of guesses. Naming conventions supply the keys: id is marked PK, and a trailing id or Id is marked FK. That is a guess about intent, not a fact about the data, so correct it if it reads wrong: Several collections at once: From the database itself To draw what is really there — including tables no model covers — read the schema and adapt that: This is the honest picture: it comes from the catalog, not from your model definitions, so it shows drift between the two. describeTable() reports type, nullability, default, primary key and auto-increment. It does not report unique constraints or comments, so those are left blank; a trailing id is still marked FK by the same naming convention as above. Naming a diagram instead of importing it DiagramType names all fifteen generators, so the choice can come from a CLI flag, a config file or a request instead of a hand-written switch: Value | Generator | --- | --- | model | ModelDiagram | er | ERDiagram | chen | ChenDiagram | relational | RelationalDiagram | class | ClassDiagram | migration | MigrationDiagram | schemadoc | SchemaDocDiagram | index | IndexDiagram | dependency | DependencyDiagram | sequence | SequenceDiagram | state | StateDiagram | flow | FlowDiagram | tree | TreeDiagram | package | PackageDiagram | gantt | GanttDiagram | Three ways in, depending on what you need back: Each is typed against the diagram you named, so passing ERDiagramOptions for DiagramType.Model is a compile error rather than an empty picture. isDiagramType() guards a value that came from outside the program; parseDiagramType() converts one, throwing a message that lists the valid names. Keeping a diagram current Because the adapters read the live schema, regenerating is a script, not a chore — wire it into your build and the picture can never drift: Related reading Diagram generators — all fifteen, with real output ER diagram and Model diagram — what these adapters feed Models — where rawAttributes and associations come from