03 — PostgreSQL with pg
Hub › JavaScript › Advanced › 03 PostgreSQL with pg
Goal: connect to a PostgreSQL database using the pg Node.js driver, run migrations, and perform basic CRUD from a script.
Prerequisites
- PostgreSQL installed locally
- A running Postgres server on port 5432
Install pg
bash
npm install pgConnect and create a table
Create db.js:
js
const { Pool } = require("pg");
const pool = new Pool({
host: process.env.PGHOST || "localhost",
port: Number(process.env.PGPORT) || 5432,
user: process.env.PGUSER || "postgres",
password: process.env.PGPASSWORD || "postgres",
database: process.env.PGDATABASE || "todos",
});
async function migrate() {
await pool.query(`
CREATE TABLE IF NOT EXISTS todos (
id SERIAL PRIMARY KEY,
text TEXT NOT NULL,
done BOOLEAN NOT NULL DEFAULT false,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
`);
console.log("Migration complete");
}
module.exports = { pool, migrate };Create the database
bash
createdb todosRun the migration
Create bin/migrate.js:
js
const { migrate } = require("../db");
migrate()
.then(() => process.exit(0))
.catch((err) => {
console.error(err);
process.exit(1);
});bash
node bin/migrate.js
# Migration completeCRUD helpers
Add these to db.js:
js
async function getAllTodos() {
const { rows } = await pool.query(
"SELECT * FROM todos ORDER BY id"
);
return rows;
}
async function createTodo(text) {
const { rows } = await pool.query(
"INSERT INTO todos (text) VALUES ($1) RETURNING *",
[text]
);
return rows[0];
}
async function updateTodo(id, fields) {
const setClauses = [];
const values = [];
let idx = 1;
if (fields.done !== undefined) {
setClauses.push(`done = $${idx++}`);
values.push(fields.done);
}
if (fields.text) {
setClauses.push(`text = $${idx++}`);
values.push(fields.text);
}
if (setClauses.length === 0) return null;
values.push(id);
const { rows } = await pool.query(
`UPDATE todos SET ${setClauses.join(", ")} WHERE id = $${idx} RETURNING *`,
values
);
return rows[0] || null;
}
async function deleteTodo(id) {
const { rowCount } = await pool.query(
"DELETE FROM todos WHERE id = $1",
[id]
);
return rowCount > 0;
}
module.exports = { pool, migrate, getAllTodos, createTodo, updateTodo, deleteTodo };Checkpoint
bash
node -e "
const { createTodo, getAllTodos } = require('./db');
createTodo('hello from pg').then(() => getAllTodos()).then(console.log).then(() => process.exit());
"
# [ { id: 1, text: 'hello from pg', done: false, created_at: 2026-07-05T... } ]Next: 04 REST API