SQLite User Forum

Foreign Key does not work
Login

Foreign Key does not work

(1) By anonymous on 2022-07-10 20:38:47 [link] [source]

Hey im trying to use foreign keys, but it does not work.
This is my schema:
CREATE TABLE museum (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        name TEXT, 
        address TEXT 
        );

CREATE TABLE exhibition (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        name TEXT NOT NULL, 
        museum_id INTEGER,
        FOREIGN KEY(museum_id) REFERENCES museum(id) 
        );
This gets filled with data:
let db = new sqlite3.Database(DBSOURCE, (err) => {
if (err) {
    // Cannot open database
    console.error(err.message)
    throw err
} else {
    console.log('Connected to the SQLite database.')
    db.exec(fs.readFileSync('schema.sql').toString(),
        (err) => {
            if (err) {
                console.error(err.message)
            } else {
                // Table just created, creating some rows
                var insert = 'INSERT INTO museum (name, address) VALUES (?,?)'
                db.run(insert, ["museum1", "adress 1"])
                db.run(insert, ["museum2", "adress 2"])

                var insert = 'INSERT INTO exhibition (name, museum_id) VALUES (?,?)'
                db.run(insert, ["exhi1", 1])
                db.run(insert, ["exhi2", 2])
            }
        });
}
});
I read that I need to enable PRAGMA foreign_keys.
I tried that in various different ways (in the schema, outside, as seperate command, etc).
The result is all the time the same:
[Error: SQLITE_CONSTRAINT: FOREIGN KEY constraint failed
Emitted 'error' event on Statement instance at:
] {
  errno: 19,
  code: 'SQLITE_CONSTRAINT'
}
The outcome is like this:
id	   name	   museum_id
1	   exhi1   1

So for some reason just the connection to the first museum worked while the second failed? When not enabeling the pragma I will get no error using the same schema, but I asume then I dont have the foreign keys? I also would asume that I get an error when I use the foreign key without having the feature activated?

Any help is appreciated, ty.

(2) By Larry Brasfield (larrybr) on 2022-07-10 21:30:05 in reply to 1 [link] [source]

I was unable to see what you are doing ineffectively. So I added this to your DDL:

INSERT INTO museum (name, address) VALUES
 ('museum1', 'address 1'), ('museum2', 'address 2');

PRAGMA foreign_keys=1;

INSERT INTO exhibition (name, museum_id) VALUES
 ('exhi1', 1), ('exhi2', 2);

.header on
SELECT * FROM museum;
SELECT * FROM exhibition;

It runs in the sqlite3 shell without any problem or complaint.

The cure for your trouble is likely to be a closer match between the above and whatever it is that you are doing.

(9) By Gunter Hick (gunter_hick) on 2022-07-11 08:18:42 in reply to 2 [link] [source]

Should it not be

INSERT INTO exhibition (name, museumId) VALUES
('exhi1', SELECT ROWID FROM museum WHERE name='museum1'),
('exhi2', SELECT ROWID FROM museum WHERE name='museum2');

(10) By Larry Brasfield (larrybr) on 2022-07-11 18:16:24 in reply to 9 [link] [source]

I agree with the technical thinking behind this suggestion. However, generally, I do not undertake a revamp where somebody poses a specific problem which appears to simply illustrate their difficulty. This is in support of an incremental approach to discovering what has gone wrong.

(3) By Larry Brasfield (larrybr) on 2022-07-10 21:35:38 in reply to 1 [source]

When not enabeling the pragma I will get no error using the same schema, but I asume then I dont have the foreign keys?

If you do not run PRAGMA foreign_keys=1 , then you will have no enforcement of foreign key reference validity. You may or may not have any foreign keys.

I also would asume that I get an error when I use the foreign key without having the feature activated?

I would advise less assuming and more doc consultation. Start here.

(4) By anonymous on 2022-07-10 22:13:01 in reply to 3 [link] [source]

Thank you for the response! I already read the doc multiple times, also looked through many stackoverflow posts. Basically trying to fix this issue since like 6-7 hours now.

Now I did what you said:

var insert = 'INSERT INTO museum (name, address) VALUES (?,?)'
                db.run(insert, ["museum1", "adress 1"])
                db.run(insert, ["museum2", "adress 2"])

                db.run("PRAGMA foreign_keys=1")

var insert = 'INSERT INTO exhibition (name, museum_id) VALUES (?,?)'
                db.run(insert, ["exhi1", 1])
                db.run(insert, ["exhi2", 2])

Still the same issue. Same error and the tables are also no filled correct. Just one exhibition is added.

Could there be another reason?

(5) By Larry Brasfield (larrybr) on 2022-07-10 22:43:53 in reply to 4 [link] [source]

What happens if you run the following?

PRAGMA foreign_keys=1;
INSERT INTO museum (name, address) VALUES ('museum1', 'address 1');
INSERT INTO exhibition (name, museum_id) VALUES ('exhi1', last_insert_rowid());
INSERT INTO museum (name, address) VALUES ('museum2', 'address 2');
INSERT INTO exhibition (name, museum_id) VALUES ('exhi2', last_insert_rowid());

(6) By Keith Medcalf (kmedcalf) on 2022-07-11 00:51:24 in reply to 1 [link] [source]

What is the total content (select * from museum;) of the museum table, and what is the total content (select * from exhibition;) of the exhibition table?

Mayhaps that sheds light?

(7) By anonymous on 2022-07-11 01:21:05 in reply to 6 [link] [source]

hmm I used the node-sqlite3 for nodejs. It seems that this is just buggy or I dont know. I just tried another not so common package called better-sqlite3 and with that it works flawless.

thank you both very much for trying to help!! =)

(8) By Gunter Hick (gunter_hick) on 2022-07-11 07:06:52 in reply to 1 [link] [source]

You are assuming that the museumIDs are 1 and 2 respectively. This may not be true. Maybe the probably completey unneccesary AUTOINCREMENT clause is preventing the re-use of ids 1 and 2.