Version control your database schema with migrations. Create, modify, and rollback changes safely.
Create tables and modify schema
Rollback changes safely
Track and rollback by batch
Fluent API for table creation
1import { Schema, defineMigration } from "canxjs";23defineMigration(4"create_users_table",56// UP: Create the table7async () => {8await Schema.create("users", (table) => {9table.id(); // BIGINT primary key10table.string("name"); // VARCHAR(255)11table.string("email").unique(); // VARCHAR(255) UNIQUE12table.string("password");13table.string("role").default("user");14table.text("bio").nullable(); // TEXT, can be NULL15table.boolean("is_active").default(true);16table.timestamps(); // created_at, updated_at17});18},1920// DOWN: Drop the table21async () => {22await Schema.drop("users");23}24);
| Method | SQL Type |
|---|---|
| id() | BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY |
| string(name, len?) | VARCHAR(255) |
| text(name) | TEXT |
| integer(name) | INT |
| boolean(name) | TINYINT(1) |
| datetime(name) | DATETIME |
| json(name) | JSON |
1await Schema.create("products", (table) => {2table.id(); // BIGINT AUTO_INCREMENT PRIMARY KEY3table.string("name", 100); // VARCHAR(100)4table.text("description"); // TEXT5table.integer("quantity"); // INT6table.bigInteger("views"); // BIGINT7table.float("weight"); // FLOAT8table.decimal("price", 10, 2); // DECIMAL(10,2)9table.boolean("is_available"); // TINYINT(1)10table.date("release_date"); // DATE11table.datetime("published_at"); // DATETIME12table.timestamp("verified_at"); // TIMESTAMP13table.json("metadata"); // JSON14table.binary("thumbnail"); // BLOB15table.timestamps(); // created_at, updated_at16table.softDeletes(); // deleted_at17});
1await Schema.create("posts", (table) => {2table.id();3table.string("title");4table.string("slug").unique(); // Unique constraint5table.text("content").nullable(); // Allow NULL values6table.string("status").default("draft"); // Default value7table.integer("views").unsigned(); // Unsigned integer8table.integer("category_id").index(); // Add index9table.timestamps();10});
1await Schema.create("posts", (table) => {2table.id();3table.string("title");4table.text("content");56// Foreign key with cascade delete7table.bigInteger("user_id").unsigned()8.references("users", "id")9.onDelete("CASCADE");1011table.bigInteger("category_id").unsigned()12.references("categories", "id")13.onDelete("SET NULL");1415table.timestamps();16});
1import { migrator } from "canxjs";23// Run all pending migrations4await migrator.run();56// Rollback last batch7await migrator.rollback();89// Reset all migrations (rollback all)10await migrator.reset();1112// Fresh: reset and re-run all13await migrator.fresh();1415// Check migration status16const status = await migrator.status();17console.log(status);18// [{ name: "create_users_table", ran: true }, ...]
1# Run pending migrations2bunx canx migrate34# Rollback last batch5bunx canx migrate:rollback67# Reset all migrations8bunx canx migrate:reset910# Fresh migration (reset + run)11bunx canx migrate:fresh1213# Check migration status14bunx canx migrate:status
1// Check if table exists2const exists = await Schema.hasTable("users");34// Check if column exists5const hasEmail = await Schema.hasColumn("users", "email");67// Rename table8await Schema.rename("posts", "articles");910// Drop table if exists11await Schema.dropIfExists("temp_data");