Updated for nself v0.4.8
nself uses a schema-first approach with DBML (Database Markup Language) for designing, managing, and evolving your database schema with automatic migration generation.
nself v0.4.8 provides comprehensive schema tools through the nself db schema command suite. Design your schema visually at dbdiagram.io, import DBML files, or use pre-built templates to get started quickly.
Your schema is defined in schema.dbml file:
// Example schema.dbml
Project nself_project {
database_type: 'PostgreSQL'
Note: 'nself project database schema'
}
Table users {
id uuid [pk, default: `gen_random_uuid()`]
email varchar(255) [unique, not null]
name varchar(255) [not null]
password_hash varchar(255) [not null]
email_verified boolean [default: false]
created_at timestamp [default: `now()`, not null]
updated_at timestamp [default: `now()`, not null]
Note: 'User accounts and authentication'
}
Table profiles {
id uuid [pk, default: `gen_random_uuid()`]
user_id uuid [ref: > users.id, not null]
first_name varchar(100)
last_name varchar(100)
avatar_url varchar(500)
bio text
created_at timestamp [default: `now()`, not null]
updated_at timestamp [default: `now()`, not null]
}
Table posts {
id uuid [pk, default: `gen_random_uuid()`]
user_id uuid [ref: > users.id, not null]
title varchar(255) [not null]
content text
status post_status [default: 'draft']
published_at timestamp
created_at timestamp [default: `now()`, not null]
updated_at timestamp [default: `now()`, not null]
indexes {
user_id
status
(user_id, status)
published_at [where: 'published_at IS NOT NULL']
}
}
Enum post_status {
draft
published
archived
}# 1. Create a starter schema from template
nself db schema scaffold basic # Also: ecommerce, saas, blog
# 2. Edit schema.dbml (or use dbdiagram.io to design)
# 3. Apply everything in one command:
nself db schema apply schema.dbml # Import -> migrate -> seed# Create starter schema from template
nself db schema scaffold <template> # basic, ecommerce, saas, blog
# Convert DBML to SQL migration
nself db schema import <file.dbml>
# Full workflow: import -> migrate -> seed
nself db schema apply <file.dbml># Show current schema
nself db schema
# Show specific table schema
nself db schema show users
# Compare schema between environments
nself db schema diff staging
# Generate DBML from database (reverse engineer)
nself db schema diagram
# Export schema to SQL file
nself db schema export > schema.sql# Analyze and suggest indexes
nself db schema indexes
# Example output:
# Index Recommendations
# ─────────────────────
# [HIGH] orders.user_id - Frequently joined, no index
# [MEDIUM] products.category_id - Used in WHERE clauses
# [LOW] users.created_at - Occasional range queriesTable table_name {
id uuid [pk, default: `gen_random_uuid()`]
name varchar(255) [not null, unique]
email varchar(255) [not null, note: 'User email address']
age integer [default: 0]
created_at timestamp [default: `now()`]
// Table-level note
Note: 'Description of this table'
}pk - Primary keynot null - Not null constraintunique - Unique constraintdefault: value - Default valueincrement - Auto incrementnote: 'description' - Column documentationTable users {
id uuid [pk]
email varchar(255)
}
Table posts {
id uuid [pk]
user_id uuid [ref: > users.id] // Many-to-one relationship
title varchar(255)
}
// Alternative relationship syntax
Ref: posts.user_id > users.id
// One-to-many relationship
Ref: users.id < posts.user_id
// Many-to-many relationship
Ref: posts.id <> tags.idTable posts {
id uuid [pk]
user_id uuid
title varchar(255)
status varchar(50)
created_at timestamp
indexes {
user_id // Simple index
(user_id, status) // Composite index
title [type: hash] // Hash index
created_at [type: btree] // B-tree index
status [where: 'status != "draft"'] // Partial index
title [unique] // Unique index
}
}Enum user_role {
admin
moderator
user
guest
}
Enum post_status {
draft [note: 'Draft posts not visible to public']
published
archived
deleted
}
Table users {
role user_role [default: 'user']
status user_status [not null]
}Start with pre-built schema templates:
nself db schema scaffold basic
# Creates: users, profiles, postsnself db schema scaffold ecommerce
# Creates: users, products, categories, orders, order_items, cart_itemsnself db schema scaffold saas
# Creates: organizations, users, organization_members, invitations, projects, api_keysnself db schema scaffold blog
# Creates: users, posts, categories, tags, post_categories, post_tags, comments, mediaDesign your schema visually at dbdiagram.io, then import:
# Import DBML and create SQL migration
nself db schema import schema.dbml
# This creates:
# nself/migrations/20260122_imported_schema.up.sql
# nself/migrations/20260122_imported_schema.down.sqlGenerate DBML from your existing database:
nself db schema diagram > schema.dbml
# Open the generated file at dbdiagram.io to visualize// Before
Table users {
id uuid [pk]
email varchar(255)
name varchar(255)
}
// After - Adding phone column
Table users {
id uuid [pk]
email varchar(255)
name varchar(255)
phone varchar(20)
created_at timestamp [default: `now()`]
}// Before
Table users {
name varchar(100)
}
// After - Increase length and add constraint
Table users {
name varchar(255) [not null]
}// Before - Standalone tables
Table users {
id uuid [pk]
}
Table posts {
id uuid [pk]
title varchar(255)
}
// After - Adding relationship
Table posts {
id uuid [pk]
user_id uuid [ref: > users.id]
title varchar(255)
}Table tenants {
id uuid [pk]
name varchar(255) [not null]
subdomain varchar(50) [unique, not null]
created_at timestamp [default: `now()`]
}
Table users {
id uuid [pk]
tenant_id uuid [ref: > tenants.id, not null]
email varchar(255) [not null]
name varchar(255)
// Ensure email uniqueness within tenant
indexes {
(tenant_id, email) [unique]
}
}
Table posts {
id uuid [pk]
tenant_id uuid [ref: > tenants.id, not null]
user_id uuid [ref: > users.id, not null]
title varchar(255)
// Row Level Security policies will be applied
Note: 'Posts are isolated by tenant'
}Table audit_log {
id uuid [pk, default: `gen_random_uuid()`]
table_name varchar(100) [not null]
record_id uuid [not null]
action audit_action [not null]
old_values jsonb
new_values jsonb
user_id uuid [ref: > users.id]
timestamp timestamp [default: `now()`, not null]
indexes {
table_name
record_id
user_id
timestamp
(table_name, record_id)
}
}
Enum audit_action {
INSERT
UPDATE
DELETE
}Apply a complete workflow from DBML to working database:
nself db schema apply schema.dbmlThis automatically:
Compare your local schema with another environment:
nself db schema diff staging
# Example output:
# Schema Differences (local vs staging)
# ────────────────────────────────────
# + Table: user_preferences (missing in staging)
# ~ Column: users.last_login (different type)
# - Index: idx_orders_date (missing in local)Generate typed interfaces from your database schema:
# Generate TypeScript types
nself db types typescript
# Generate Go structs
nself db types go
# Generate Python dataclasses
nself db types python
# Generate to specific directory
nself db types typescript --output src/types/
# Include comments
nself db types typescript --comments# Problem: Import fails with parse error
# Solution: Check DBML syntax:
# - Column names must be valid identifiers
# - Types must be supported
# - Brackets must be balanced
# Validate at dbdiagram.io before importing# Check status and repair if needed
nself db migrate status
nself db migrate repair # Fix tracking table# Rollback last migration
nself db migrate down
# Rollback specific number of migrations
nself db migrate down 2
# Restore from backup if needed
nself db restore# Schema commands (v0.4.8)
nself db schema # Show current schema
nself db schema scaffold basic # Create from template
nself db schema import file.dbml # DBML to SQL migration
nself db schema apply file.dbml # Import + migrate + seed
nself db schema diagram # Database to DBML
nself db schema diff staging # Compare schemas
nself db schema show users # Show table schema
nself db schema indexes # Suggest indexes
nself db schema export # Export to SQL
# Type generation
nself db types typescript # Generate TS types
nself db types go # Generate Go structs
nself db types python # Generate Python types