xiaohongshu
xiaohongshu
db-diagram
Generate database ER diagrams from schema for documentation
Full skill instructions
I'll help you generate comprehensive Entity-Relationship diagrams from your database schema, supporting multiple ORMs and output formats.
Arguments: $ARGUMENTS - schema files, output format (mermaid/plantuml/dbml), or ORM type
This skill uses diagram generation-specific patterns to minimize token usage:
Pattern: Cache parsed schema structure to avoid re-analysis
db-diagram/schema-snapshot.json (24 hour TTL)Pattern: Detect schema changes and return existing diagram
Pattern: Use Mermaid/PlantUML templates instead of creative generation
Pattern: Use mermaid-cli or plantuml.jar for rendering
mmdc -i diagram.mmd -o diagram.png (200 tokens)java -jar plantuml.jar diagram.puml (200 tokens)Pattern: Analyze first 20 tables for relationship patterns
Pattern: Three-tier diagram depth
Pattern: Find table definitions with Grep
^model, CREATE TABLE, @Entity (200 tokens)Pattern: Update only changed portions of diagram
Typical operation patterns:
Expected per-generation: 1,500-2,500 tokens (50% reduction from 3,000-5,000 baseline) Real-world average: 700 tokens (due to cached snapshots, early exit, template-based generation)
I'll maintain diagram generation sessions for tracking schema evolution:
Session Files (in current project directory):
db-diagram/diagrams/ - Generated diagram filesdb-diagram/schema-snapshot.json - Current schema structuredb-diagram/state.json - Generation history and settingsdb-diagram/relationships.md - Documented relationshipsIMPORTANT: Session files are stored in a db-diagram folder in your current project root
Auto-Detection:
generate, update, compare, exportFor complex database schemas, I'll use extended thinking to understand relationships:
<think> When analyzing database schemas: - Implicit relationships not explicitly defined in ORM - Many-to-many relationships through junction tables - Polymorphic associations and their representations - Inheritance strategies (single table, joined table, table per class) - Soft deletes and audit columns - Database-level constraints vs application-level validations - Normalized vs denormalized design patterns </think>Triggers for Extended Analysis:
I'll automatically detect your database setup:
#!/bin/bash
# ORM and schema detection
detect_database_stack() {
echo "=== Database Stack Detection ==="
# Prisma detection
if [ -f "prisma/schema.prisma" ]; then
echo "✓ Prisma detected: prisma/schema.prisma"
ORM="prisma"
SCHEMA_FILE="prisma/schema.prisma"
fi
# TypeORM detection
if find . -name "*.entity.ts" | head -1; then
echo "✓ TypeORM detected: *.entity.ts files"
ORM="typeorm"
SCHEMA_FILES=$(find . -name "*.entity.ts")
fi
# Sequelize detection
if [ -d "models" ] && grep -q "sequelize" package.json 2>/dev/null; then
echo "✓ Sequelize detected: models/ directory"
ORM="sequelize"
SCHEMA_FILES=$(find models -name "*.js" -o -name "*.ts")
fi
# SQLAlchemy (Python) detection
if find . -name "models.py" | head -1; then
echo "✓ SQLAlchemy detected: models.py"
ORM="sqlalchemy"
SCHEMA_FILES=$(find . -name "models.py")
fi
# Django detection
if find . -path "*/models/*.py" | head -1; then
echo "✓ Django detected: */models/*.py"
ORM="django"
SCHEMA_FILES=$(find . -path "*/models/*.py")
fi
# Drizzle detection
if find . -name "schema.ts" | grep -q drizzle; then
echo "✓ Drizzle detected"
ORM="drizzle"
SCHEMA_FILES=$(find . -name "schema.ts")
fi
# Raw SQL detection
if find . -name "*.sql" | grep -qE "(schema|create|ddl)"; then
echo "✓ SQL files detected"
ORM="raw-sql"
SCHEMA_FILES=$(find . -name "*.sql" | grep -iE "(schema|create|ddl)")
fi
if [ -z "$ORM" ]; then
echo "⚠️ No recognized ORM/schema files found"
echo "Supported: Prisma, TypeORM, Sequelize, SQLAlchemy, Django, Drizzle"
return 1
fi
echo
echo "ORM: $ORM"
echo "Schema files: $SCHEMA_FILE $SCHEMA_FILES"
}
I'll parse schema definitions into a structured format:
# Parse Prisma schema
parse_prisma_schema() {
local schema_file=$1
echo "Parsing Prisma schema..."
# Extract models
awk '/^model / {
model=$2;
print "MODEL:" model;
in_model=1;
next;
}
in_model && /^}/ {
in_model=0;
print "END_MODEL";
next;
}
in_model && /^[[:space:]]+[a-zA-Z]/ {
print "FIELD:" $0;
}
/^enum / {
print "ENUM:" $2;
}' "$schema_file" > db-diagram/parsed-schema.txt
# Extract relationships
grep -E "@relation|@@" "$schema_file" > db-diagram/relationships.txt
}
Parsed Schema Structure:
{
"models": [
{
"name": "User",
"fields": [
{"name": "id", "type": "Int", "primaryKey": true, "autoIncrement": true},
{"name": "email", "type": "String", "unique": true},
{"name": "name", "type": "String", "nullable": true},
{"name": "posts", "type": "Post[]", "relation": true}
]
},
{
"name": "Post",
"fields": [
{"name": "id", "type": "Int", "primaryKey": true},
{"name": "title", "type": "String"},
{"name": "authorId", "type": "Int"},
{"name": "author", "type": "User", "relation": {"from": "authorId", "to": "id"}}
]
}
],
"relationships": [
{
"from": "Post",
"to": "User",
"type": "many-to-one",
"fromField": "author",
"toField": "posts"
}
]
}
// Parse TypeORM entities (conceptual - would use AST parsing)
/*
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column({ unique: true })
email: string;
@OneToMany(() => Post, post => post.author)
posts: Post[];
}
Extracts to:
- Entity: User
- Primary Key: id (auto-generated)
- Unique: email
- Relationship: OneToMany to Post
*/
# Parse SQLAlchemy models (conceptual)
"""
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
email = Column(String, unique=True)
posts = relationship('Post', back_populates='author')
Extracts to:
- Table: users
- Model: User
- Primary Key: id
- Relationship: one-to-many to Post
"""
I'll generate diagrams in multiple formats:
Advantages:
# Generate Mermaid ER diagram
generate_mermaid() {
local output_file="db-diagram/diagrams/schema.mmd"
cat > "$output_file" <<'EOF'
erDiagram
USER ||--o{ POST : "writes"
USER {
int id PK
string email UK
string name
datetime createdAt
}
POST ||--o{ COMMENT : "has"
POST {
int id PK
string title
text content
int authorId FK
datetime publishedAt
}
COMMENT {
int id PK
text content
int postId FK
int userId FK
datetime createdAt
}
USER ||--o{ COMMENT : "writes"
POST }o--|| CATEGORY : "belongs to"
CATEGORY {
int id PK
string name UK
string slug
}
POST }o--o{ TAG : "tagged with"
TAG {
int id PK
string name UK
}
POST_TAG {
int postId FK
int tagId FK
}
POST ||--o{ POST_TAG : ""
TAG ||--o{ POST_TAG : ""
EOF
echo "Mermaid diagram generated: $output_file"
echo
echo "View in GitHub/GitLab, or use:"
echo " - https://mermaid.live"
echo " - VSCode Mermaid Preview extension"
}
Relationship Notation:
||--o{ : one to many
}o--|| : many to one
||--|| : one to one
}o--o{ : many to many
Advantages:
# Generate PlantUML diagram
generate_plantuml() {
local output_file="db-diagram/diagrams/schema.puml"
cat > "$output_file" <<'EOF'
@startuml Database Schema
!define Table(name,desc) class name as "desc" << (T,#FFAAAA) >>
!define primary_key(x) <b>PK: x</b>
!define foreign_key(x) <color:red>FK: x</color>
!define unique(x) <color:green>UK: x</color>
Table(User, "users") {
primary_key(id): INT
unique(email): VARCHAR
name: VARCHAR
createdAt: TIMESTAMP
}
Table(Post, "posts") {
primary_key(id): INT
title: VARCHAR
content: TEXT
foreign_key(authorId): INT
publishedAt: TIMESTAMP
}
Table(Comment, "comments") {
primary_key(id): INT
content: TEXT
foreign_key(postId): INT
foreign_key(userId): INT
createdAt: TIMESTAMP
}
Table(Category, "categories") {
primary_key(id): INT
unique(name): VARCHAR
slug: VARCHAR
}
Table(Tag, "tags") {
primary_key(id): INT
unique(name): VARCHAR
}
Table(PostTag, "post_tags") {
foreign_key(postId): INT
foreign_key(tagId): INT
}
User "1" -- "0..*" Post : writes
User "1" -- "0..*" Comment : writes
Post "1" -- "0..*" Comment : has
Post "0..*" -- "1" Category : belongs to
Post "0..*" -- "0..*" Tag : tagged with
(Post, Tag) .. PostTag
@enduml
EOF
echo "PlantUML diagram generated: $output_file"
echo
echo "Generate image:"
echo " plantuml $output_file"
echo " # or use: https://www.plantuml.com/plantuml/"
}
Advantages:
# Generate DBML diagram
generate_dbml() {
local output_file="db-diagram/diagrams/schema.dbml"
cat > "$output_file" <<'EOF'
// Database Schema Documentation
// Generated: 2026-01-25
Table users {
id integer [pk, increment]
email varchar [unique, not null]
name varchar
createdAt timestamp [default: `now()`]
Indexes {
email [unique]
}
}
Table posts {
id integer [pk, increment]
title varchar [not null]
content text
authorId integer [ref: > users.id]
categoryId integer [ref: > categories.id]
publishedAt timestamp
Indexes {
authorId
categoryId
publishedAt
}
}
Table comments {
id integer [pk, increment]
content text [not null]
postId integer [ref: > posts.id]
userId integer [ref: > users.id]
createdAt timestamp [default: `now()`]
}
Table categories {
id integer [pk, increment]
name varchar [unique, not null]
slug varchar [unique, not null]
}
Table tags {
id integer [pk, increment]
name varchar [unique, not null]
}
Table post_tags {
postId integer [ref: > posts.id]
tagId integer [ref: > tags.id]
Indexes {
(postId, tagId) [pk]
}
}
// Relationships
Ref: posts.authorId > users.id [delete: cascade]
Ref: comments.postId > posts.id [delete: cascade]
Ref: comments.userId > users.id [delete: cascade]
EOF
echo "DBML diagram generated: $output_file"
echo
echo "Visualize at: https://dbdiagram.io/d"
}
I'll automatically detect and document relationships:
# Detect relationship types
detect_relationships() {
echo "=== Relationship Analysis ==="
# One-to-Many
echo "One-to-Many relationships:"
# User -> Posts: A user has many posts
# Post -> Comments: A post has many comments
# Many-to-Many
echo "Many-to-Many relationships:"
# Post <-> Tag: Posts have many tags, tags have many posts
# (via post_tags junction table)
# One-to-One
echo "One-to-One relationships:"
# User -> Profile: A user has one profile
# Self-referential
echo "Self-referential relationships:"
# User -> User: A user can follow other users
# Category -> Category: Categories can have parent categories
}
# Document relationships
document_relationships() {
cat > db-diagram/relationships.md <<EOF
# Database Relationships
## One-to-Many Relationships
### User → Posts
- **Cardinality**: One User has Many Posts
- **Foreign Key**: \`posts.authorId\` references \`users.id\`
- **Cascade**: Delete posts when user is deleted
- **Inverse**: \`user.posts\` / \`post.author\`
### Post → Comments
- **Cardinality**: One Post has Many Comments
- **Foreign Key**: \`comments.postId\` references \`posts.id\`
- **Cascade**: Delete comments when post is deleted
- **Inverse**: \`post.comments\` / \`comment.post\`
## Many-to-Many Relationships
### Posts ↔ Tags
- **Cardinality**: Many-to-Many
- **Junction Table**: \`post_tags\`
- **Foreign Keys**:
- \`post_tags.postId\` references \`posts.id\`
- \`post_tags.tagId\` references \`tags.id\`
- **Inverse**: \`post.tags\` / \`tag.posts\`
## One-to-One Relationships
### User → Profile
- **Cardinality**: One-to-One
- **Foreign Key**: \`profiles.userId\` references \`users.id\`
- **Unique**: \`profiles.userId\` is unique
- **Inverse**: \`user.profile\` / \`profile.user\`
EOF
}
I'll generate comprehensive schema documentation:
# Database Schema Documentation
Generated: 2026-01-25 18:45:00
## Overview
- **Database**: PostgreSQL 15
- **ORM**: Prisma
- **Tables**: 6
- **Relationships**: 8
## Tables
### users
User accounts and authentication
| Column | Type | Constraints | Description |
|-----------|-----------|-----------------------|----------------------|
| id | integer | PRIMARY KEY, AUTO_INC | User identifier |
| email | varchar | UNIQUE, NOT NULL | Login email |
| name | varchar | NULLABLE | Display name |
| createdAt | timestamp | DEFAULT NOW() | Account creation |
**Indexes:**
- PRIMARY KEY on `id`
- UNIQUE INDEX on `email`
**Relationships:**
- One-to-Many: `posts` (via `posts.authorId`)
- One-to-Many: `comments` (via `comments.userId`)
---
### posts
Blog posts and articles
| Column | Type | Constraints | Description |
|-------------|-----------|-----------------------|----------------------|
| id | integer | PRIMARY KEY, AUTO_INC | Post identifier |
| title | varchar | NOT NULL | Post title |
| content | text | NULLABLE | Post body |
| authorId | integer | FOREIGN KEY, NOT NULL | Author reference |
| categoryId | integer | FOREIGN KEY | Category reference |
| publishedAt | timestamp | NULLABLE | Publication date |
**Indexes:**
- PRIMARY KEY on `id`
- INDEX on `authorId`
- INDEX on `categoryId`
- INDEX on `publishedAt`
**Relationships:**
- Many-to-One: `author` (references `users.id`)
- Many-to-One: `category` (references `categories.id`)
- One-to-Many: `comments` (via `comments.postId`)
- Many-to-Many: `tags` (via `post_tags`)
[... additional tables ...]
## Relationship Diagram
\`\`\`mermaid
[Generated Mermaid diagram here]
\`\`\`
## Database Statistics
- **Total Tables**: 6
- **Total Columns**: 32
- **Foreign Keys**: 7
- **Unique Constraints**: 5
- **Indexes**: 12
## Change History
- 2026-01-25: Initial schema
- [Track schema migrations here]
Track schema changes over time:
# Compare current schema with previous snapshot
compare_schemas() {
local previous="db-diagram/schema-snapshot.json"
local current="db-diagram/schema-current.json"
if [ ! -f "$previous" ]; then
echo "No previous schema snapshot found"
return 1
fi
echo "=== Schema Changes Detected ==="
# Compare tables
echo "New tables:"
diff <(jq -r '.models[].name' "$previous" | sort) \
<(jq -r '.models[].name' "$current" | sort) | \
grep "^>" | sed 's/^> / + /'
echo "Removed tables:"
diff <(jq -r '.models[].name' "$previous" | sort) \
<(jq -r '.models[].name' "$current" | sort) | \
grep "^<" | sed 's/^< / - /'
# Compare fields within tables
echo "Modified tables:"
# [Field comparison logic]
# Generate migration summary
cat > db-diagram/migration-summary.md <<EOF
# Schema Migration Summary
Date: $(date +"%Y-%m-%d %H:%M:%S")
## Changes
### Added Tables
- [List new tables]
### Modified Tables
- [List modified tables with field changes]
### Removed Tables
- [List removed tables]
## Impact Analysis
- **Breaking Changes**: [Yes/No]
- **Migration Required**: [Yes/No]
- **Data Migration**: [Yes/No]
## Recommended Actions
1. Review changes
2. Create migration script
3. Update API contracts
4. Update documentation
EOF
}
Integration with /schema-validate:
When schema changes detected:
→ Automatically suggest /schema-validate
→ Validate foreign key integrity
→ Check for orphaned records
→ Verify constraint compliance
Session Resume:
When you return and run /db-diagram or /db-diagram update:
Progress Example:
DATABASE DIAGRAM GENERATION
═══════════════════════════════════════════════════
Schema: Prisma (prisma/schema.prisma)
Last generated: 3 hours ago
Schema Status:
├── Tables: 6 (unchanged)
├── Relationships: 8 (unchanged)
├── Migrations: 2 new since last diagram
Changes Detected:
├── ✓ Added index on posts.publishedAt
└── ✓ Modified users.email (added validation)
Generating updated diagrams...
├── Mermaid: db-diagram/diagrams/schema.mmd
├── PlantUML: db-diagram/diagrams/schema.puml
└── DBML: db-diagram/diagrams/schema.dbml
Documentation updated: db-diagram/README.md
Generate Diagrams:
/db-diagram # Auto-detect and generate
/db-diagram mermaid # Generate Mermaid format
/db-diagram prisma/schema.prisma # Specific schema file
/db-diagram all # All formats
Update & Compare:
/db-diagram update # Regenerate with changes
/db-diagram compare # Compare with previous version
/db-diagram export svg # Export as image
Protection Measures:
Important: I will NEVER:
Perfect complement to database workflows:
/schema-validate - Validate after diagram generation/migration-generate - Create migrations from schema/docs - Include diagrams in documentation/api-docs-generate - Link schema to API docsTo stay within 2,500-4,000 token budget:
I'll help you visualize and document your database schema for better understanding and team collaboration.
Credits:
xiaohongshu
technical spec
product ux expert
database patterns
Conduct multi-agent task orchestration and workflow coordination.
Initialize project with Conductor artifacts (product definition,
Expert in web animations, transitions, and motion design using Framer Motion and CSS
Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...
PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.
Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...
Display project status, active tracks, and next actions
Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.
Generate, edit, and beat-sync AI video with leading models in one workspace.
The world's fastest calendar for remote work
Transform Your Design with AI Designer by ImgCreator.ai
Revolutionizing Video Production with AI-Powered Creativity
Extend an image past the frame and let AI fill the new aspect ratio.
Discover your celebrity doppelgänger with StarByFace!
ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.
Opus.ai: Revolutionize Your Web Experience