Preface
Automatic markdown documents generator for Prisma.
Example markdown document generated by
prisma-markdown
When developing a backend system, I draw ERD (Entity Relationship Diagram) first. And then, write a document describing the ERD to educate companions. After those designings and documentations, I start developing the backend server with ORM programming.
By the way, as the pre-designed ERD can't be perfect as I'm not a god, schema structures of database often being changed during the development. Those changes sometimes come from change of requirements, and sometimes come from my mistake that omitting principle concepts. Anyway, in that case, I have to re-draw the ERD, and re-write the document. It's so annoying and hard to managing.
To avoid such a duplicated job, I'd tried to find a proper tool that can generate ERD and describing documents automatically from the schema file. However, none of them could satisfy me. There had not been any tool which can generate both ERD and document at the same time. Even in the ERD case, none of them working properly when hundreds of tables come, either.
Therefore, I made it by myself. If you're a prisma user and need to write document decribing the database design, let's automate it. From now on, I'll show you how to install and build the documents from the prisma schema file. Let's enjoy the new world.
Setup
At first, install NPM package.
npm i -D prisma-markdown
At next, add the generator to the schema file, and write documentation comments on models and columns with ///
symbols.
generator markdown {
provider = "prisma-markdown"
title = "Shopping Mall"
output = "./ERD.md"
}
/// Describe table.
///
/// @namespace Actors
model some_users {
/// Describe column.
id String @id @db.Uuid
}
At last, run below command, than ERD.md
file would be generated.
npx prisma generate
Comment Tags
If your database has over hundreds of models, none of automatic ERD generators can express them perfect. In that case, prisma-markdown
recommends you to separate hundreds of models to multiple paginated diagrams by using /// @namepsace <name>
comments.
When you write /// @namepsace <name>
comment on models, they would be separated to proper sections of markdown document. For reference, you can assign multiple @namepsace
s to a model, and if you do not assign any @namepsace
to a model, it would be assigned to default
tag.
Also, if you use @erd <name>
instead of @namespace <name>
, target model would be expressed only at ERD. It would not be appeared to the markdown content section. Otherwise, @describe <name>
tag will show the model only at markdown content section, not at ERD.
-
@namespace <name>
: Both ERD and markdown content -
@erd <name>
: Only ERD -
@describe <name>
: Only markdown content -
@hidden
: Neither ERD nor markdown content
/// Both description and ERD on Actors chatper.
///
/// Also, only ERD on Articles and Orders chapters.
///
/// @namespace Actors
/// @erd Articles
/// @erd Orders
model shopping_customers {}
/// Only description on Actors chapter.
///
/// @describe Actors
model shopping_customer_login_histories {}
/// Only ERD on Articles chapter.
///
/// @erd Articles
model shopping_sale_reviews {}
/// Never be shown.
///
/// @hidden
model shopping_sale_hits {}
Demonstration
To show how prisma-markdown
works, I desinged a shopping mall database, well-known to everyone. When defining a model scheme, write description comment with ///
symbol like below. After that, run npx prisma generate
command, then markdown document with ERD diagrams would be automatically generated.
Prisma Schema File
generator markdown {
provider = "prisma-markdown"
title = "Shopping Mall"
output = "./ERD.md"
}
/// Product composition information handled in the sale snapshot.
///
/// shopping_sale_snapshot_units
is an entity that embodies the
/// "individual product" information handled in the
/// {@link shopping_sale_snapshots sale snapshot}.
///
/// For reference, the reason why shopping_sale_snapshot_units
is separated
/// from {@link shopping_sale_snapshots} by an algebraic relationship of
/// 1: N is because there are often cases where multiple products are sold
/// in one listing. This is the case with so-called "bundled products".
///
/// - Bundle from regular product (laptop set)
/// - main body
/// - keyboard
/// - mouse
/// - Apple Care (Free A/S Voucher)
///
/// And again, shopping_sale_snapshot_units
does not in itself refer to
/// the final {@link shopping_sale_snapshot_unit_stocks stock} that the
/// customer will purchase.
/// The {@link shopping_sale_snapshot_unit_stocks final stock} can be
/// found only after selecting all given
/// {@link shopping_sale_snapshot_unit_options options} and their
/// {@link shopping_sale_snapshot_unit_option_candidates candidate} values.
///
/// For example, even if you buy a laptop, the
/// {@link shopping_sale_snapshot_unit_stocks final stocks} are determined
/// only after selecting all the
/// {@link shopping_sale_snapshot_unit_options options} (CPU / RAM / SSD), etc.
///
/// @namespace Sales
/// @erd Carts
/// @author Samchon
model shopping_sale_snapshot_units {
//----
// COLUMNS
//----
/// @format uuid
id String @id @db.Uuid
/// Belonged snapshot's {@link shopping_sale_snapshots.id}
///
/// @format uuid
shopping_sale_snapshot_id String @db.Uuid
/// Representative name of the unit.
name String @db.VarChar
/// Whether the unit is primary or not.
///
/// Just a labeling value.
primary Boolean @db.Boolean
/// Whether the unit is required or not.
///
/// When the unit is required, the customer must select the unit. If do
/// not select, customer can't buy it.
required Boolean @db.Boolean
/// Sequence order in belonged snapshot.
sequence Int @db.Integer
//----
// RELATIONS
//----
/// Belonged snapshot.
snapshot shopping_sale_snapshots @relation(fields: [shopping_sale_snapshot_id], references: [id], onDelete: Cascade)
/// List of options.
options shopping_sale_snapshot_unit_options[]
/// List of stocks.
stocks shopping_sale_snapshot_unit_stocks[]
/// List of stocks contained in cart item
cart_item_stocks shopping_cart_item_stocks[]
}
Generated Markdown Document
shopping_sale_snapshot_units
Product composition information handled in the sale snapshot.
shopping_sale_snapshot_units
is an entity that embodies the "individual product" information handled in the sale snapshot.For reference, the reason why
shopping_sale_snapshot_units
is separated from shopping_sale_snapshots by an algebraic relationship of 1: N is because there are often cases where multiple products are sold in one listing. This is the case with so-called "bundled products".
- Bundle from regular product (laptop set)
- main body
- keyboard
- mouse
- Apple Care (Free A/S Voucher)
And again,
shopping_sale_snapshot_units
does not in itself refer to the final stock that the customer will purchase. The final stock can be found only after selecting all given options and their candidate values.For example, even if you buy a laptop, the final stocks are determined only after selecting all the options (CPU / RAM / SSD), etc.
Properties
id
:shopping_sale_snapshot_id
: Belonged snapshot's shopping_sale_snapshots.idname
: Representative name of the unit.primary
> Whether the unit is primary or not. > > Just a labeling value.required
> Whether the unit is required or not. > > When the unit is required, the customer must select the unit. If do > not select, customer can't buy it.sequence
: Sequence order in belonged snapshot.
Top comments (4)
Nice, good work!
Thanks for your share
i love this
Nice one ❤️