Data persistence uses PostgreSQL. Raw SQL builds fluency for interviews and debugging; Knex adds migrations, seeds, and a query builder your Express services call. Learn both: SQL shows what the database actually runs; Knex shows how the app stays maintainable.
Knex queries
Knex query builder methods mirror SQL CRUD: select rows, insert with returning, update, delete, and aggregate. Use these from service functions—never from router files directly.
Build SELECT queries with knex('table').where() and return rows to the caller.
Learn: Knex builds parameterized queries—safer than string concatenation. Chain where, orderBy, and first() for one row. Await the query or return the promise to the caller.
Supplementary examples
List and read one
function list() {
return knex("pastes").select("paste_id", "name").orderBy("created_at", "desc");
}
function read(id) {
return knex("pastes").where({ paste_id: id }).first();
}
Course example
function listTotalWeightByProduct() {
return knex("products")
.select(
"product_sku",
"product_title",
knex.raw(
"sum(product_weight_in_lbs * product_quantity_in_stock) as total_weight_in_lbs"
)
)
.groupBy("product_title", "product_sku");
}
Change or remove rows using update(), del(), or delete() with filters.
Learn: update(patch) and del() (or delete()) should always include where filters. Check the number of affected rows to distinguish 404 from success.
Supplementary examples
Update and delete by id
function update(id, patch) {
return knex("pastes").where({ paste_id: id }).update(patch);
}
function remove(id) {
return knex("pastes").where({ paste_id: id }).del();
}
Count, group, or summarize rows using query builder aggregates and JavaScript post-processing.
Learn: Aggregates answer summary questions: how many rows, totals, averages. Use count(), sum(), or raw selects with GROUP BY; post-process in JavaScript when shaping nested API responses.
Supplementary examples
Count pastes per user
return knex("pastes")
.select("user_id")
.count("* as paste_count")
.groupBy("user_id");
Course example
function listOutOfStockCount() {
return knex("products")
.select("product_quantity_in_stock as out_of_stock")
.count("product_id")
.where({ product_quantity_in_stock: 0 })
.groupBy("out_of_stock");
}