Exercise 3: The foreign_keys PRAGMA Gotcha vs. MySQL/Postgres's Default — Possible Solution ==================================================================== THE GOTCHA ------------------------------ Per this chapter's own warn-box, "SQLite genuinely supports foreign key constraints, but does not enforce them by default — enforcement must be explicitly turned on per connection with PRAGMA foreign_keys = ON;. Forgetting this setting silently allows orphaned or invalid foreign key references to be inserted with no error at all." WHAT THIS MEANS CONCRETELY ------------------------------ A table can be defined with a genuine FOREIGN KEY constraint — referencing, say, a customer_id column back to a customers table's own id column — and SQLite will accept that table definition without complaint. But unless PRAGMA foreign_keys = ON; has been explicitly run on the CURRENT connection, that constraint isn't actually enforced: an INSERT or UPDATE that references a customer_id value with no matching row in the customers table will simply succeed, silently creating an orphaned reference, exactly as if the foreign key constraint had never been declared at all. Because this setting is per-connection rather than a permanent, database-wide setting, it has to be remembered and set every single time a new connection is opened — easy to forget, especially since the table definition itself still LOOKS like it should be enforcing the constraint. WHY THIS IS A GENUINELY DIFFERENT DEFAULT FROM MYSQL/POSTGRES ------------------------------ Per this chapter, "this is a genuinely different default from MySQL (with InnoDB) or Postgres, where foreign key enforcement is simply on with no equivalent opt-in step required." In MySQL (using the InnoDB storage engine, the modern default) and in Postgres, a declared foreign key constraint is enforced automatically and immediately — there's no separate setting to remember to turn on, no per-connection step at all. A developer coming from either of those systems, and therefore not expecting to need any extra step, could easily assume a SQLite foreign key constraint is being enforced simply because it was declared in the schema — and be wrong, silently, until an actual data integrity problem surfaces later from the accumulated orphaned references. WHY THIS WORKS AS AN ANSWER ------------------------------ It explains precisely what "not enforced by default" means in practice (a declared constraint that's silently ignored unless explicitly turned on per connection), and explicitly contrasts this against MySQL/Postgres's own on-by-default behavior, naming exactly why someone coming from either system is especially likely to be caught by this gotcha.