5

I am trying to create a POST route as shown below. My Timesheet table has a FOREIGN KEY constraint set on it referencing the Employee table. When I try and insert a timesheet from an employee that doesn't exist using DB Browser I get the correct error triggered by the constraint. However, when I run the code below, it ignores this constraint and inserts the record. Have I set this up incorrectly or is this not a valid constraint under this scenario?

timesheetRouter.post("/", getParams, (req, res, next) => {
    const tsData = req.body.timesheet;
    console.log("ID", req.empID);
    db.run(`insert into Timesheet (hours, rate, date, employee_id) 
        values ($hours, $rate, $date, $emp);`, {
        $hours: tsData.hours,
        $rate: tsData.rate,
        $date: tsData.date,
        $emp: req.empID
    }, function(err) {
        if (err) {
            return res.status(404).send(err);
        } else {
            db.get("select * from Timesheet where id = $id", {$id: this.lastID},
                (err, row) => {
                    return res.status(201).send({timesheet: row});
                });
        }
    });
});

Table creation code:

db.serialize(() => {
    db.run("DROP TABLE IF EXISTS Timesheet", err => {
        if (err) {
            throw new Error(err);
        }
    });
    db.run(`create table Timesheet (id integer PRIMARY KEY,
        hours integer NOT NULL,
        rate integer NOT NULL,
        date integer NOT NULL,
        employee_id integer NOT NULL, FOREIGN KEY (employee_id) REFERENCES Employee (id))`,
    err => {
        if (err) {
            throw new Error(err);
        }
    });
});

Note: getParams is a function to determine the value for empID.

1 Answer 1

18

Currently, in SQLite version 3.25.2 foreign key constraints are disabled by default. You need to turn them on by

sqlite> PRAGMA foreign_keys = ON;

Or, in your case

db.get("PRAGMA foreign_keys = ON")

I assume.

It works on a per-connection basis, DB Browser probably automatically sets it on start up, that's why it triggers an error in that case.

Sign up to request clarification or add additional context in comments.

2 Comments

So this would need to be run each time the query is run? Just checking what you mean by per-connection.
Not for every query, just once for every db object. I assume you have a let db = new sqlite3.Database(':memory:'); or something similar somewhere. You just need to turn foreign key support on after that, and it will remain enabled until you close the db or re-assign a new connection to it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.