Intro to KNEX
Querybuilding & You!
Objectives
- Define what a Querybuilder is and articulate the benefits
- Set up a new project with Knex
- Perform CRUD on a resource using Knex methods
You'll revisit these!
Knex - What is it good for?
(absolutely everything)
- Abstraction
- Conditional Filters
- Security
- Database Engine Interoperability
- Migrations
- Seeds
Knex - What does it look like?
knex('pokemon').select().then(function(data) {
console.log(data);
process.exit(1);
});
pg.query("SELECT * FROM pokemon;", function(err, data) {
console.log(data);
process.exit(1);
});
pg
knex
Knex - What does it look like?
knex('pokemon').select().then(function(data) {
console.log(data);
});
Table Name
Operation
Promise
Returned rows
Knex - Abstraction
const goldAndSilverStart = 152;
const goldAndSilverEnd = 251;
knex('pokemon').select()
.whereBetween('pokedex_number', [goldAndSilverStart, goldAndSilverEnd])
.then(function(data) {
console.log(data);
process.exit(1);
});
const goldAndSilverStart = 152;
const goldAndSilverEnd = 251;
pg.query("SELECT * FROM pokemon WHERE pokedex_number BETWEEN $1 AND $2",
[goldAndSilverStart, goldAndSilverEnd],
function(err, data) {
console.log(data);
process.exit(1);
});
pg
knex
PG - Conditional Filters
var games = {
gold : {
start: 152,
end: 251
},
red : {
start: 1,
end: 151
}
};
router.get("/api/pokemon", function(req, res, next) {
var query = "SELECT * FROM pokemon ";
var params = [];
if (req.query) {
if (req.query.game) {
query += "WHERE pokedex_number BETWEEN ? AND ? ";
params.push(games[req.query.game.start]);
params.push(games[req.query.game.start]);
}
if (req.query.type) {
if (req.query.game) {
query += "AND ";
} else {
query += "WHERE ";
}
query += " (type1 = ? OR type2 = ?)";
params.push(req.query.type);
params.push(req.query.type);
}
}
query += ";"
pg.query(query, params, function(err, data){
req.send(data);
})
});
Knex - Conditional Filters
var games = {
gold : {
start: 152,
end: 251
},
red : {
start: 1,
end: 151
}
};
router.get("/api/pokemon", function(req, res, next) {
var query = knex('pokemon').select()
if (req.query) {
if (req.query.game) {
query.whereBetween('pokedex_number', [games[req.query.game.start], games[req.query.game.start]])
}
if (req.query.type) {
query.where({type1: req.query.type}).orWhere({type2: req.query.type})
}
}
query.then(function(data) {
res.json(data)
});
});
Objectives
- Define what a Querybuilder is and articulate the benefits
- Set up a new project with Knex
- Perform CRUD on a resource using Knex methods
Discuss:
What is a Querybuilder?
Where would we use querybuilders?
Where can we find out how to use knex?
Knex - Setup
$ npm install knex -g
$ express pokemon && cd pokemon
$ npm install
$ npm install --save pg knex
$ knex init
Install Globally (for cli tools)
Install locally too (for deploy)
Initialize and Configure
Init new app, enter directory
Install Express
Knex - Setup
module.exports = {
development: {
client: 'pg',
connection: 'postgres://localhost:5432/pokemon',
debug: true
},
production: {
client: 'pg',
connection: process.env.DATABASE_URL
}
};
Knex - Migrations
$ knex migrate:make add_sprites
Make a migration file
exports.up = function(knex, Promise) {
return knex.schema.createTable('sprites', function(table){
table.increments();
table.string('url');
table.integer('pokemon_id').references('pokemon.id').notNullable();
table.string('type');
});
};
exports.down = function(knex, Promise) {
return knex.schema.dropTable('sprites');
};
$ knex migrate:latest
Run the migration
Knex - Migrations - Update
$ knex migrate:make add_base_experience_to_pokemon
exports.up = function(knex, Promise) {
return knex.schema.table('pokemon', function(table){
table.string('base_experience');
});
};
exports.down = function(knex, Promise) {
return knex.schema.dropColumn('base_experience');
};
$ knex migrate:latest
Run the migration
Knex - Seeds
$ knex seed:make insert_sprites
Create a seed file
exports.seed = function(knex, Promise) {
return Promise.join(
// Deletes ALL existing entries
knex('moves').del(),
// Inserts seed entries
knex('moves').insert({name: 'cut', type: "normal"}),
knex('moves').insert({name: 'fly', type: "flying"}),
knex('moves').insert({name: 'sand attack', type: "normal"}),
knex('moves').insert({name: 'splash', type: "water"})
);
};
$ knex seed:run
Run the migration
Objectives
Time for a CFU!
- Define what a Querybuilder is and articulate the benefits
- Set up a new project with Knex
- Perform CRUD on a resource using Knex methods
Reflect
Look at how sprites are seeded - can you modify the moves to insert from the API?
Why would we use migrations instead of raw SQL?
Do This - 25 mins:
- Create a migration to make a Pokemon table
- Create a migration for a Berries table
- Insert at least 5 berries
CRUD with Knex
router.get("/pokemon", function(req,res){
knex('pokemon').select().where('pokedex_number', '>', 100).then(function(pokemon) {
res.json(pokemon);
});
});
router.get("/sprites", function(req, res) {
knex('spirites').select().then(function(sprites){
res.render('pokepictures', {sprites: sprites})
});
});
router.post("/sprites", function(req,res) {
knex("sprites").insert({url: req.body.url, pokemon_id: req.body.pokemon.id, type: req.body.type}).then(function() {
res.send("Success")
}).catch(function(e) {
res.json(e)
});
});
Objectives
- Define what a Querybuilder is and articulate the benefits
- Set up a new project with Knex
- Perform CRUD on a resource using Knex methods
Check Your Understanding
Add a route to display all moves, called /moves, and get data from Knex
Add a /pokemon/search route
- ?name={a pokemon name}
- ?type={a type}
- ?name={a pokemon name}&type={a pokemon type}
30 mins
Intro to KNEX
By LizTheDeveloper
Intro to KNEX
- 1,822