Database
Sequelize
Introduction
JCC Express MVC supports Sequelize as an alternative SQL ORM when DB_ORM=sequelize. Models live in app/Models/ and use Sequelize's class + Model.init(...) pattern — not JCC Eloquent's Model from jcc-express-mvc/Eloquent.
When enabled, the framework registers the connection as:
database.connectionsequelize
Resolve it with app.resolve("sequelize") or the global app helper during bootstrap.
Enable Sequelize
app/Config/database.ts includes the expected sequelize block:
sync.alter updates tables to match your models in development. Keep sync.force and dropTables disabled in production unless you intentionally reset schema.
Required packages
For PostgreSQL or SQLite, install the matching dialect driver (pg, better-sqlite3, etc.).
Generate models
With DB_ORM=sequelize, ArtisanNode scaffolds Sequelize models:
Files are created in app/Models/. On connect, the framework loads every .ts / .js file in that folder, registers models, and runs static associate on each class that defines it.
Model file structure
Each Sequelize model file should:
- Import
Model,DataTypes, andSequelizefrom thesequelizepackage. - Resolve the shared connection with
app.resolve<Sequelize>("sequelize"). - Extend Sequelize's
Modelclass anddeclaretyped attributes. - Define
static associate(models)for relationships (optional). - Call
ModelName.init(attributes, options)at the bottom of the file. - Export a class whose name matches the filename (e.g.
Test.tsexportsclass Test) so autoloading can register it.
Example (app/Models/Test.ts):
Model.init options
| Option | Purpose |
|---|---|
sequelize | Shared connection from app.resolve("sequelize") |
tableName | Database table name |
modelName | Sequelize model name (used for route model binding suffix) |
timestamps | When true, Sequelize manages createdAt / updatedAt |
Add columns in the first argument to init using DataTypes (STRING, TEXT, BOOLEAN, DATE, JSON, etc.).
Full example: User model
Relationships (associate)
After all models in app/Models/ are loaded, the framework calls static associate(models) on each model. The models argument is a map of loaded classes keyed by filename (User, Post, etc.).
Models are loaded in filename sort order. Define foreign keys on child models and wire associate after both sides exist — parent models that appear earlier in the alphabet are available when associate runs on child models.
Using models in controllers
Import the model class from app/Models/:
Use standard Sequelize query APIs on the model class and instances.
Route model binding
When DB_ORM=sequelize, implicit binding resolves models with findByPk from the route parameter (e.g. {user} → User.findByPk(id)). See Routing.
Column binding ({email$user}) uses Sequelize findOne({ where: { email } }).
Access the Sequelize connection
For raw queries or transactions outside model classes:
What happens on connect
When DB_ORM=sequelize, the framework:
- Creates the Sequelize instance from
app/Config/database.ts. - Authenticates against the database.
- Requires every model file in
app/Models/and collects exported classes. - Calls
associate(models)on each model that defines it. - Runs
sequelize.sync(...)using yoursyncconfig.
Summary
- Set
DB_ORM=sequelizeand configuredatabase.sequelizein app config. - Models live in
app/Models/— usesequelize'sModel+Model.init, not JCC Eloquent. - Resolve the connection with
app.resolve<Sequelize>("sequelize")in each model file. - Define relationships in
static associate(models). - Generate scaffolds with
bun artisanNode make:model <Name>. - Query with Sequelize APIs (
findAll,findByPk,create, etc.).