question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Foreign key constraints not working in SQLite

See original GitHub issue

I 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:closed
  • Created 4 years ago
  • Reactions:1
  • Comments:9 (3 by maintainers)

github_iconTop GitHub Comments

6reactions
Tapaccommented, Sep 8, 2020

@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" ?

0reactions
Tapaccommented, Sep 8, 2020

Hurray! Then I’ll close the issue.

Read more comments on GitHub >

github_iconTop 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 >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found