Database Models
Morphis models are a thin application-layer wrapper on top of your database table. They define which connection to use, which table to read from, and give you a consistent query API.
Naming convention
Morphis expects your database schema to stay database-friendly:
- table names should be
snake_caseand usually plural - column names should be
snake_case - model class names should be
PascalCase - application code can keep using
camelCase
If you do not set static tableName, Morphis infers it from the class name as:
User->usersBlogPost->blog_postsCompanyCategory->company_categories
That means the recommended pattern is:
import { Model } from 'morphis'
export class BlogPost extends Model {
static connection = 'default'
}and the matching table in SQL should be:
CREATE TABLE blog_posts (
id INTEGER PRIMARY KEY,
title TEXT NOT NULL,
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
);Application-layer normalization
Morphis automatically normalizes keys between your application layer and the database layer:
- input like
createdAtcan map to a column namedcreated_at - rows returned from the database are mapped back to
camelCasewhere possible - plain object
whereclauses such as{ createdAt: '...' }are normalized to the real column
Example:
await BlogPost.create({
title: 'First post',
createdAt: new Date().toISOString(),
})Even if the actual column is created_at, the model layer will resolve it for you.
When to set tableName
Set static tableName only when the inferred name is not the real table name.
import { Model } from 'morphis'
export class Person extends Model {
static connection = 'default'
static tableName = 'users'
}Full example
import { Model } from 'morphis'
export class User extends Model {
static connection = 'default'
}
const user = await User.create({
firstName: 'Kent',
lastName: 'Ng',
})
const rows = await User.findAll({
where: { firstName: 'Kent' },
})With a database schema like:
CREATE TABLE users (
id INTEGER PRIMARY KEY,
first_name TEXT NOT NULL,
last_name TEXT NOT NULL
);Recommendation
Keep the database schema in snake_case, keep your TypeScript in camelCase, and let Morphis handle the mapping. That is the convention the model layer is built around.