This skill should be used when the user asks about "Atlas HCL syntax", "define schema in Atlas", "create tables in HCL", "foreign keys in Atlas", "indexes in Atlas", "schema.hcl file", "Atlas data types", "constraints in HCL", "SQL schema definition", "column types in Atlas", or needs guidance on writing database schemas using HCL, SQL, or ORM formats
Define your database schema using HCL, SQL, or ORM declarations. This skill covers syntax, best practices, and common patterns.
HCL is Atlas's native schema language with powerful features like templates and validation.
schema "public" {
comment = "Standard public schema"
}
table "users" {
schema = schema.public
comment = "User accounts"
column "id" {
type = bigint
auto_increment = true
comment = "Primary key"
}
column "email" {
type = varchar(255)
null = false
comment = "User email address"
}
column "created_at" {
type = timestamp
default = sql("CURRENT_TIMESTAMP")
}
primary_key {
columns = [column.id]
}
index "idx_email" {
columns = [column.email]
unique = true
}
}
column "name" {
type = varchar(100) # String with max length
}
column "age" {
type = int # Integer
}
column "balance" {
type = decimal(10, 2) # Decimal with precision
}
column "active" {
type = bool
default = true # Boolean with default
}
column "metadata" {
type = json # JSON type
}
column "created" {
type = timestamp
default = sql("CURRENT_TIMESTAMP")
}
column "tags" {
type = text
null = true # Nullable column
}
table "posts" {
schema = schema.public
column "id" {
type = bigint
auto_increment = true
}
column "user_id" {
type = bigint
}
column "title" {
type = varchar(255)
null = false
}
column "content" {
type = text
}
primary_key {
columns = [column.id]
}
# Foreign key constraint
foreign_key "fk_user" {
columns = [column.user_id]
ref_columns = [table.users.column.id]
on_delete = CASCADE
on_update = CASCADE
}
# Unique constraint
index "idx_unique_title_user" {
columns = [column.title, column.user_id]
unique = true
}
# Check constraint
check "content_not_empty" {
expr = "content IS NOT NULL OR title IS NOT NULL"
}
}
# Single column index
index "idx_status" {
columns = [column.status]
}
# Composite index
index "idx_user_created" {
columns = [column.user_id, column.created_at]
}
# Unique index
index "idx_unique_email" {
columns = [column.email]
unique = true
}
# Partial index (database-specific)
index "idx_active_users" {
columns = [column.email]
where = "active = true"
}
Use standard DDL when you prefer SQL or need specific database features:
-- Create schema
CREATE SCHEMA IF NOT EXISTS public;
-- Create users table
CREATE TABLE public.users (
id BIGSERIAL PRIMARY KEY,
email VARCHAR(255) NOT NULL UNIQUE,
name VARCHAR(255),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Create posts table with foreign key
CREATE TABLE public.posts (
id BIGSERIAL PRIMARY KEY,
user_id BIGINT NOT NULL,
title VARCHAR(255) NOT NULL,
content TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE,
UNIQUE(user_id, title)
);
-- Create indexes
CREATE INDEX idx_posts_user ON public.posts(user_id);
CREATE INDEX idx_posts_created ON public.posts(created_at);
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
title String
user User @relation(fields: [userId], references: [id])
userId Int
}
Atlas can derive the database schema from Prisma and use it for migrations.
type User struct {
ID uint
Email string `gorm:"uniqueIndex"`
Name string
Posts []Post
}
type Post struct {
ID uint
Title string
UserID uint
User User
}
my-project/
├── atlas.hcl # Project configuration
├── schema.hcl # Desired schema definition
└── migrations/
├── 20240101120000_create_users.sql
├── 20240102120000_create_posts.sql
└── 20240103120000_add_index.sql
// atlas.hcl - Central configuration
env "local" {
url = "mysql://root:password@localhost:3306/mydb"
dev = "mysql://root:password@localhost:3306/mydb_dev"
migration {
dir = "file://migrations"
format = sql
}
schema {
src = "file://schema.hcl"
}
format {
migrate {
apply = "-- Applying schema changes\n\n{{ sql . }}\n"
}
}
}
INT, BIGINT, SMALLINTVARCHAR(n), TEXTNUMERIC(p,s), DECIMAL(p,s)BOOLEANTIMESTAMP, DATE, TIMEJSON, JSONBUUIDARRAYINT, BIGINT, SMALLINTVARCHAR(n), TEXTDECIMAL(p,s), FLOATBOOLEAN (alias for TINYINT)TIMESTAMP, DATETIME, DATE, TIMEJSONENUMINTEGERTEXTREALBLOBtable "users" {
column "id" { type = bigint; auto_increment = true }
column "email" { type = varchar(255); null = false }
primary_key { columns = [column.id] }
index "idx_email" { columns = [column.email]; unique = true }
}
table "posts" {
column "id" { type = bigint; auto_increment = true }
column "user_id" { type = bigint; null = false }
column "title" { type = varchar(255) }
primary_key { columns = [column.id] }
foreign_key "fk_user" {
columns = [column.user_id]
ref_columns = [table.users.column.id]
on_delete = CASCADE
}
}
For complete schema documentation, see:
references/atlas-docs-full/docs.md - Schema-as-code overviewreferences/atlas-docs-full/guides/orms/ - Complete ORM integration guidesreferences/README.md - Full documentation index