Foreign key constraints not working in SQLite
See original GitHub issueI created a sample database where the Albums table references the Artist table. I am using SQLite. I can delete an artist even when it is referenced from the Albums table. (With H2, this fails as it should with a ForeignKey exception.) I tried to set PRAGMA foreign_keys = ON, but this does not help either. Do I miss some hidden option?
Test code.
object Artists : IntIdTable() {
val name = varchar("name", length = 100)
}
object Albums : IntIdTable() {
val title = varchar("title", 250)
val artistId = reference("artistId", Artists)
// onDelete = ReferenceOption.CASCADE,
// onUpdate = ReferenceOption.CASCADE)
}
fun testSQLiteFK() {
File("fktest.db").delete()
Database.connect("jdbc:sqlite:fktest.db", "org.sqlite.JDBC")
TransactionManager.manager.defaultIsolationLevel =
Connection.TRANSACTION_SERIALIZABLE
transaction {
addLogger(StdOutSqlLogger)
SchemaUtils.create(Artists)
SchemaUtils.create(Albums)
val pfId = Artists.insertAndGetId { it[name] = "Pink Floyd" }
Albums.insert {
it[title] = "Dark side of the moon"
it[artistId] = pfId
}
}
transaction {
addLogger(StdOutSqlLogger)
// should fail because of FK constraint
Artists.deleteWhere { Artists.name eq "Pink Floyd" }
}
transaction {
addLogger(StdOutSqlLogger)
// explicitly enabling foreign keys (?)
// does not help
val sql = "PRAGMA foreign_keys = ON"
connection.executeInBatch(listOf(sql))
for (row in Artists.selectAll())
println(row)
// no output
for (row in Albums.selectAll())
println(row)
// Albums.id=1, Albums.title=Dark side of the moon, Albums.artistId=1
// refers to no longer existing artist
}
}
// SQL logging
// SQL: CREATE TABLE IF NOT EXISTS Artists (id INTEGER PRIMARY KEY AUTOINCREMENT, "name" VARCHAR(100) NOT NULL)
// SQL: CREATE TABLE IF NOT EXISTS Albums (id INTEGER PRIMARY KEY AUTOINCREMENT, title VARCHAR(250) NOT NULL, artistId INT NOT NULL, CONSTRAINT fk_Albums_artistId_id FOREIGN KEY (artistId) REFERENCES Artists(id) ON DELETE RESTRICT ON UPDATE RESTRICT)
// SQL: INSERT INTO Artists ("name") VALUES ('Pink Floyd')
// SQL: INSERT INTO Albums (artistId, title) VALUES (1, 'Dark side of the moon')
// SQL: DELETE FROM Artists WHERE Artists."name" = 'Pink Floyd'
// SQL: PRAGMA foreign_keys = ON
// SQL: SELECT Artists.id, Artists."name" FROM Artists
// SQL: SELECT Albums.id, Albums.title, Albums.artistId FROM Albums
Issue Analytics
- State:
- Created 4 years ago
- Reactions:1
- Comments:9 (3 by maintainers)
Top Results From Across the Web
sqlite - Foreign Key constraint doesn't work - Stack Overflow
For those who are looking for how to enable foreign key support you need to change your ConnectionString to "data source=C:\Dbs\myDb.db;foreign ...
Read more >SQLite Foreign Key Support
If foreign key constraints are enabled when it is prepared, the DROP TABLE command performs an implicit DELETE to remove all rows from...
Read more >SQLite Foreign Key: Enforce Relationships Between Tables
This tutorial shows you how to use the SQLite foreign key constraint to enforce the relationships between correlated tables.
Read more >Primary Key and Foreign Key in SQLite with Examples - Guru99
Note that Foreign keys constraints are not enabled by default in SQLite, you have to enable them first by the running the following...
Read more >SQLite Foreign Key not working : r/learnpython - Reddit
Foreign key constraints are disabled by default (for backwards compatibility ), so must be enabled separately for each database connection.
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
@connected-rmcleod , @kovbe11 , @MichaelKofler , as I understand from documentation foreign_keys should be enabled on connection level and PRAGMA will have no effect if it wasn’t enabled. Could you please check your code with adding
?foreign_keys=on
to connection url like:"jdbc:sqlite:data.db?foreign_keys=on"
?Hurray! Then I’ll close the issue.