Objection.js | SQL friendly ORM for Node.js

Node.js has plenty of object-relational mappers (for relational databases) that we can choose from few popular ones are:

  1. Sequelize
  2. Mongoose or Prisma
  3. TypeORM
  4. Objection.js (Read the full documentation here)

Why consider Objection.js?
So here are few reasons to consider using it:

  • Easy way to define models and relationships between them.
  • Create queries with Node’s async/await.
  • Use eager-loading and transactions with your models.
  • Work with nested documents in rows.
  • Powerful mechanisms for inserting and upserting object graphs.
  • TypeScript support and JSON schema validation.

The following steps have to be followed to install and use Objection.js:

So the way you install it is to install two dependencies: knex and objection using the following command:

npm i knex -g --save
npm i objection --save

Knex is a powerful SQL query builder (it is used a whole bunch of different ORMs). So under the hood, objection uses Knex. Besides building SQL queries, Knex is used to establish database connections and pooling connections. It is also used for managing database schemas via migrations. 



You might also need to install a database driver for whatever SQL database you want to use. Some various options available, just install them using the following command:

npm i pg
npm i sqlite3
npm i mysql
npm i mariasql

Creating a Database:
Filename: app.js

filter_none

edit
close

play_arrow

link
brightness_4
code

const { Client } = require('pg');
const { db } = require('./config');
const client = new Client();
  
(async () => {
  await client.connect();
  await client.query(`CREATE DATABASE ${db.connection.database}`);
  await client.end();
})();

chevron_right


Creating Migrations:

  • Migrations allow you to apply a change to a database schema in a step-by-step manner.
  • The “up” action applies a change (creating a table, adding/modifying a column, etc.).
  • The “down” action applies the reverse action of the change (eg. if a migration’s “up” action creates a table, it’s equivalent “down” action will drop the table).
  • Knex will create a migration folder (unless it exists already).
  • It then creates a file in the migrations folder for the migration.
knex migrate:make create_tasks_table

The generate migrations will look something like this:

Filename: empty_migration.js

filter_none

edit
close

play_arrow

link
brightness_4
code

exports.up = function (knex, Promise) {
};
  
exports.down = function (knex, Promise) {
};

chevron_right


Now we can perform certain actions like creating a table:
Filename: knex_migration.js

filter_none

edit
close

play_arrow

link
brightness_4
code

const tableName = 'tasks';
  
exports.up = knex => {
  
  // Create the tasks table
  return knex.schema.createTable(tableName, table => {
    table.increments('id').primary();
    table.string('name');
    table.date('due_by');
    table.boolean('is_done').defaultTo(false);
    table.timestamps(true, true);
    table.unique(['name']);
  });
};
  
exports.down = knex => {
  
  // Drop the tasks table
  return knex.schema.dropTableIfExists(tableName);
};

chevron_right


Now, if you want to run them, then the following code will execute it:

knex migrate:latest

Models:



  • Models are the wrappers around the database tables.
  • They help to encapsulate the business logic within those tables (relations, validations, indexes, triggers).
  • Objection.js allows you to create Models using ES6 classes.

A really nice and simple example is shown below:
Filename: TaskModel.js

filter_none

edit
close

play_arrow

link
brightness_4
code

// Task Model
const { MODEL } = require('objection');
const db = require('../db');
  
// Pass he knex connection to Objection
Model.knex(db);
  
class Task extends Model {
  
  // Tells objection what the db 
  // table is for the model
  static get tableName() {
    return 'tasks';
  }
}
  
module.exports = Task;

chevron_right


The project structure will look like this:

  • Simple Select Query:
    Filename: select_query.sql

    SELECT * from tasks;

    Can be done with:
    Filename: objection_select_query.js

    const tasks = await Task.query();
  • Typical SELECT Query:
    Filename: standard_select_query.sql

    SELECT * from tasks WHERE is_done = false ORDER BY due_by asc;

    Can be done with:
    Filename: objection_standard_select_query.js

    const tasks = await Task.query()
        .where({is_done: false}).orderBy('due_by');
  • Insert Query:
    Filename: insert_query.sql

    INSERT INTO tasks (name) VALUES ('Setup Code Coverage');

    Can be done with:
    Filename: objection_insert_query.js

    await Task.query().insert({ name: 'Setup Code Coverage' });
  • Update Query:
    Filename: update_query.sql

    UPDATE tasks SET is_done = true WHERE id = 1;

    Can be done with:
    Filename: objection_insert_query.js

    await Task.query().patch({ is_done: true }).where({ id: 1 });

If we use the objection_standard_query.js file to check the output then the output will look something like this:

So the Objection queries are really powerful and easy to use.




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.


Article Tags :

Be the First to upvote.


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.