
Security News
Django Joins curl in Pushing Back on AI Slop Security Reports
Django has updated its security policies to reject AI-generated vulnerability reports that include fabricated or unverifiable content.
simple-knex-model
Advanced tools
A simple model for knex queries.
Inspired a bit by objection, but with way less features. On the plus side, it works with es6 modules.
yarn add simple-knex-model knex
# or npm install --save simple-knex-model knex
Configure your knex instance and provide it to the base model. This can be done any time before you use a model instance, and subsequent calls are safe.
import BaseModel from 'simple-knex-model';
import knex from 'knex';
const knexConfig = {};
const db = knex(knexConfig);
BaseModel.knex(db);
Then define your models.
import BaseModel from 'simple-knex-model';
export default class User extends BaseModel {
static get tableName() { // required
return 'users';
}
static get primaryKey() { // optional
return 'id'; // default value
}
static get jsonSchema() { // optional
return {
type: 'object',
required: ['name', 'email'],
properties: {
id: { type: 'string' },
name: { type: 'string' },
email: { type: 'string', format: 'email' },
status: { type: 'string', enum: ['pending', 'approved', 'denied'] },
},
};
}
}
If you provide a jsonSchema
, documents will be validated with it before they are saved.
Model
here is your model, which extends BaseModel
(simple-knex-model);
new Model(document)
Creates a new instance of the model, ready to be saved. Document is an object.
modelInstance.save()
Inserts the document into the database. Returns a promise. If jsonSchema
is defined on the model, it will be used to validate the document before saving, and the Promise will reject if the validation fails.
Model.query()
Returns an instance of knex
, with the table name already applied. Use this to execute any of the normal knex
operations.
Model.queryById(id)
Returns an instance of knex
, with the table name already applied and a where on the primary key for the provided id. Use this to execute any of the normal knex
operations on documents with a given id. Most useful when used with .first()
.
Model.queryWith(relations)
relations
is either a key from the relationships object or an array of said keys. Returns an instance of knex
, with the table name already applied and the related join queries applied. Use this to execute any of the normal knex
operations with your defined joins.
Basic relationships are supported, using BaseModel.hasMany
, BaseModel.belongsTo
, and BaseModel.belongsToMany
. The naming should be pretty self-explanatory, but there is plenty of information around that explains how it works. Here's a quick example:
import BaseModel from 'simple-knex-model';
class Chef extends BaseModel {
static get tableName() {
return 'chefs';
}
static get relationships() {
return {
recipes: {
model: 'Recipe',
relation: BaseModel.hasMany,
remote: 'chef_id',
}
};
}
}
class Recipe extends BaseModel {
static get tableName() {
return 'recipes';
}
static get relationships() {
return {
chef: {
model: 'Chef',
relation: BaseModel.belongsTo,
local: 'chef_id',
}
};
}
}
// get all recipes and include the chef's name in the joined results
await results = Recipe.queryWith('recipes').select('chefs.name as chef', 'recipes.*');
Here's the breakdown of the options for each. If you need something more complex, you'll have to craft if by hand directly from the knex
instance.
BaseModel.hasMany
Owner model has many child models
property | default | description |
---|---|---|
model | string - Model name to join with | |
relation | BaseModel.hasMany - The model relationship type | |
joinType | inner | string - The join type to use (inner, left, right, leftOuter, rightOuter, fullOuter, cross) |
local | primaryKey | string - The local field to join with |
remote | string - The remote field to join with |
BaseModel.belongsTo
Owner model belongs to child model
property | default | description |
---|---|---|
model | string - Model name to join with | |
relation | BaseModel.belongsTo - The model relationship type | |
joinType | inner | string - The join type to use (inner, left, right, leftOuter, rightOuter, fullOuter, cross) |
local | string - The local field to join with | |
remote | primaryKey | string - The remote field to join with |
BaseModel.belongsToMany
Owner model has and belongs to many child models, coordinated through a join table
property | default | description |
---|---|---|
model | string - Model name to join with | |
relation | BaseModel.belongsToMany - The model relationship type | |
joinType | inner | string - The join type to use (inner, left, right, leftOuter, rightOuter, fullOuter, cross) |
joinTable | string - Table join table to use | |
local | primaryKey | string - The local field to join with |
joinLocal | string - The field in the join table to match on the local field | |
remote | primaryKey | string - The remote field to join with |
joinRemote | string - The field in the join table to match on the remote field |
simple-knex-model
provides 3 hooks which can be used to modify data on the fly. You can use that to create your own custom base model, or even to write plugins. For example, let's say you want to apply a custom id to documents, via uuid or some other method, you can use the onCreate
hook to do just that.
import BaseModel from 'simple-knex-model';
import crypto from 'crypto';
const rand = len => crypto.randomBytes(Math.ceil(len / 2)).toString('hex').slice(0, len);
class User extends BaseModel {
static get tableName() {
return 'users';
}
static onCreate(doc) {
doc.id = rand(12);
}
}
const user = new User({ email: 'user@email.co' });
console.log(user); // { id: 'daa92600af5d', email: 'user@email.co' }
Now every User document you create will have a random id. You could plug any GUID/UUID functionality you want in here. You can also take this idea further and create your own custom base class that adds this functionality to every model that extends it.
import BaseModel from 'simple-knex-model';
import crypto from 'crypto';
const rand = len => crypto.randomBytes(Math.ceil(len / 2)).toString('hex').slice(0, len);
class CustomModel extends BaseModel {
static onCreate(doc) {
doc.id = rand(12);
}
}
class User extends CustomModel {
static get tableName() {
return 'users';
}
}
class Post extends CustomModel {
static get tableName() {
return 'posts';
}
}
const user = new User({ email: 'user@email.co' });
const post = new Post({ title: 'Hello World' });
console.log(user); // { id: 'b8919bf858ab', email: 'user@email.co' }
console.log(post): // { id: 'f624c9ad373c', title: 'Hello World' }
onCreate(doc)
Called when a new instance of the model is created. The doc
object is passed by reference and can be mutated directly.
beforeValidate(jsonSchema, doc)
Called before the doc is validated against the defined schema. jsonSchema
is a shallow clone of the schema defined on the model, and anything returned from this function will be used as the new schema. The doc
object is passed by reference and can be mutated directly.
beforeCreate(doc, [returning])
Called after the validation but before the document is written to the database. The doc
object is passed by reference and can be mutated directly. All arguments from .insert()
are passed directly. This method can return a Promise, and the query won't execute until the Promise resolves.
beforeUpdate(doc, [returning]) / beforeUpdate(key, value, [returning])
Called after the validation but before the document update query is executed. If doc
object is provided, is it passed by reference and can be mutated directly. All arguments from .update()
are passed directly, so you should check what you get. This method can return a Promise, and the query won't execute until the Promise resolves.
MIT © w33ble
v0.4.0 (16 May 2018)
#1
#3
921eeb6
6c04ecd
cfdc8c5
d3d97e0
ddd5e8c
FAQs
A simple model for knex queries
The npm package simple-knex-model receives a total of 13 weekly downloads. As such, simple-knex-model popularity was classified as not popular.
We found that simple-knex-model demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Django has updated its security policies to reject AI-generated vulnerability reports that include fabricated or unverifiable content.
Security News
ECMAScript 2025 introduces Iterator Helpers, Set methods, JSON modules, and more in its latest spec update approved by Ecma in June 2025.
Security News
A new Node.js homepage button linking to paid support for EOL versions has sparked a heated discussion among contributors and the wider community.