SQLite many-to-many relationship?

wes picture wes · Aug 4, 2011 · Viewed 17.8k times · Source

I'm trying to set up a SQLite3 database with foos and bars and a many-to-many relation between them. This is what I've got so far:

CREATE TABLE foo(
    id INTEGER PRIMARY KEY NOT NULL,
    foo_col INTEGER NOT NULL
);
CREATE TABLE bar(
    id INTEGER PRIMARY KEY NOT NULL,
    bar_col TEXT NOT NULL
);
CREATE TABLE foobar(
    foo_id INTEGER,
    bar_id INTEGER,
    FOREIGN KEY(foo_id) REFERENCES foo(id) ON DELETE CASCADE,
    FOREIGN KEY(bar_id) REFERENCES bar(id) ON DELETE CASCADE
);
CREATE INDEX fooindex ON foobar(foo_id);
CREATE INDEX tagindex ON foobar(tag_id);

...but it doesn't seem to be working. I can delete a row from foo and it doesn't affect foobar. What am I doing wrong?

Answer

ace picture ace · Aug 4, 2011

Taken from this site, http://www.sqlite.org/foreignkeys.html.

Assuming the library is compiled with foreign key constraints enabled, it must still be enabled by the application at runtime, using the PRAGMA foreign_keys command. For example:

sqlite> PRAGMA foreign_keys = ON;

Foreign key constraints are disabled by default (for backwards compatibility), so must be enabled separately for each database connection separately. (Note, however, that future releases of SQLite might change so that foreign key constraints enabled by default. Careful developers will not make any assumptions about whether or not foreign keys are enabled by default but will instead enable or disable them as necessary.) The application can can also use a PRAGMA foreign_keys statement to determine if foreign keys are currently enabled. The following command-line session demonstrates this:

sqlite> PRAGMA foreign_keys;
0
sqlite> PRAGMA foreign_keys = ON;
sqlite> PRAGMA foreign_keys;
1
sqlite> PRAGMA foreign_keys = OFF;
sqlite> PRAGMA foreign_keys;
0

Tip: If the command "PRAGMA foreign_keys" returns no data instead of a single row containing "0" or "1", then the version of SQLite you are using does not support foreign keys (either because it is older than 3.6.19 or because it was compiled with SQLITE_OMIT_FOREIGN_KEY or SQLITE_OMIT_TRIGGER defined).

It is not possible to enable or disable foreign key constraints in the middle of a multi-statement transaction (when SQLite is not in autocommit mode). Attempting to do so does not return an error; it simply has no effect.