Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQLite3 "forgets" to use foreign keys

I'm using Ruby with SQLite3 and my attempts to use foreign keys in Sqlite3 were unfortunately not successful. According to sqlite3 --version, version 3.7.13 is installed. As far as I know, Sqlite3 supports foreign keys since version 3.6.x.

I know that foreign keys are deactivated by default and have to be activated with PRAGMA foreign_keys = ON;. In my Ruby db-create-script, I'm doing something like this:

sql = <<-SQL
  PRAGMA foreign_keys = ON;
  CREATE TABLE apps (
    id ....
  );
  CREATE TABLE requests (
    ...
    app_id INTEGER NOT NULL,
    FOREIGN KEY(app_id) REFERENCES apps(id),
  );
  ...
SQL
db.execute_batch(sql)

Unfortunately, I can happily insert rows into requests with unknown app-ids, it works, but of course it shouldn't.

Interesting: using the sqlite3 shell directly, I can observe the following behaviour:

$ sqlite3 database.db
sqlite> PRAGMA foreign_keys = ON;
sqlite> PRAGMA foreign_keys;
1 // as expected
sqlite> .quit
$ sqlite3 database.db
sqlite> PRAGMA foreign_keys;
0 // off ?!

Without quitting the sqlite3 shell, foreign keys are working after activating them (and not quitting the shell) and I'm not allowed to insert rows with unknown app_ids.

like image 626
cara Avatar asked Mar 08 '13 19:03

cara


People also ask

Does SQLite enforce foreign keys?

SQLite has supported foreign key constraint since version 3.6. 19.

What does Pragma Foreign_keys on do?

pragma foreign_keys = on enforces foreign keys. This is usually necessary because by default, SQLite does not enforce foreign keys. Explicitly turning off the validation of foreign keys might be useful when importing a . dump 'ed database.

How do foreign keys work in SQLite?

A foreign key is a way to enforce referential integrity within your SQLite database. A foreign key means that values in one table must also appear in another table. The referenced table is called the parent table while the table with the foreign key is called the child table.

What is Pragma SQLite?

The PRAGMA statement is an SQL extension specific to SQLite and used to modify the operation of the SQLite library or to query the SQLite library for internal (non-table) data.


3 Answers

I think I can answer my own question: The documentation says: Foreign key constraints are disabled by default (for backwards compatibility), so must be enabled for each database connection separately. Annoying, but it's finally working now.

like image 65
cara Avatar answered Sep 29 '22 16:09

cara


Put this at the top of the file that executes the SQL commands and it will enable foreign keys on runtime.

db = SQLite3::Database.new("database.db")
db.execute("PRAGMA foreign_keys = ON")
like image 44
oconn Avatar answered Sep 29 '22 17:09

oconn


One way of permanently turning on foreign_keys by default is to inject the following line into ~/.sqliterc:

PRAGMA foreign_keys = ON;

Please note that it will affect all your databases...

like image 26
Onlyjob Avatar answered Sep 29 '22 16:09

Onlyjob