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.

sqlite self table FOREIGN KEY constraint failed with ON DELETE RESTRICT when drop()/sync({force:true})

See original GitHub issue

Issue Description

I created a nested table that refers to itself. When it contains data, trying to execute the .drop() or .sync({force: true}) will trigger a constraint failure from sqlite.

What are you doing?

const Sequelize = require('sequelize');

const sequelize = new Sequelize({dialect: 'sqlite', storage: 'database.sqlite'});

class MyTable extends Sequelize.Model {
}

MyTable.init({
    parentId: {
        type: Sequelize.INTEGER,
        onDelete: 'RESTRICT',
        references: {
            model: MyTable,
            key: 'id'
        }
    }
}, { sequelize, modelName: 'Alarms'});

sequelize
    .sync({force: true})
    // root
    .then(_ => MyTable.build().save()
        // child
        .then(rootModel => MyTable.build({parentId: rootModel.id}).save()))

    // BOOM
    .then(_ => sequelize.sync({force: true}))
    .catch(error => console.error(error));

will output

CREATE TABLE "Alarms" (
	"id"	INTEGER PRIMARY KEY AUTOINCREMENT,
	"parentId"	INTEGER,
	"createdAt"	DATETIME NOT NULL,
	"updatedAt"	DATETIME NOT NULL,
	FOREIGN KEY("parentId") REFERENCES "Alarms"("id") ON DELETE RESTRICT
);

INSERT INTO "Alarms" (id, parentId, createdAt, updatedAt) VALUES(1, NULL, datetime('now'), datetime('now'));
INSERT INTO "Alarms" (id, parentId, createdAt, updatedAt) VALUES(2, 1, datetime('now'), datetime('now'));

What do you expect to happen?

Since I’m deleting the whole table, FK to the same table shouldn’t trigger this FK constraint.

Note: I don’t have a SQLite background, only a MSSQL/MYSQL. So this behavior is strange to me.

I did look into DROP TABLE documentation and they indeed talk about this behavior.

If foreign key constraints are enabled, a DROP TABLE command performs an implicit DELETE FROM command before removing the table from the database schema. […] An implicit DELETE FROM does cause any configured foreign key actions to take place.

I could see why this ticket could be closed as won’t do.

Environment

  • Sequelize version: 5.21.1
  • Node.js version: 10.13.0
  • Operating System: Win64

Issue Template Checklist

How does this problem relate to dialects?

  • I think this problem happens regardless of the dialect.
  • I think this problem happens only for the following dialect(s): sqlite
  • I don’t know, I was using PUT-YOUR-DIALECT-HERE, with connector library version XXX and database version XXX

Would you be willing to resolve this issue by submitting a Pull Request?

  • Yes, I have the time and I know how to start.
  • Yes, I have the time but I don’t know how to start, I would need guidance.
  • No, I don’t have the time, although I believe I could do it if I had the time…
  • No, I don’t have the time and I wouldn’t even know how to start.

Issue Analytics

  • State:open
  • Created 4 years ago
  • Comments:11 (7 by maintainers)

github_iconTop GitHub Comments

3reactions
romannepcommented, Oct 26, 2019

For some cases could help turning off foreign key constrait

await sequelize.query('PRAGMA foreign_keys = false;');
sequelize.sync({...});
await sequelize.query('PRAGMA foreign_keys = true;');
1reaction
Suisse00commented, Oct 21, 2019

I’m new to both SQLite and sequelize so I can’t suggest the best approach.

I did Google a little bit before submitting my suggestions and they did make no sense… SQLite doesn’t support to drop a column or FK… oh… crap…

So the only suggestion that left on my list is: Parse the FK constraint and delete rows ourselves in the right order. To this suggestion, I added the note (before googling): “at this point, it should probably be a user addon in a different NPM or the user should switch to ON DELETE CASCADE”

So I totally agree with you about the feature label! (if you still go ahead, and if there is nobody that already did this somewhere).

After thinking about it my recommendation would be: Close the issue. I should have know SQLite limit.

Read more comments on GitHub >

github_iconTop Results From Across the Web

BUG: DELETE / DROP TABLE fails with self referencing FK data
Even if the foreign key constraint it is attached to is deferred, configuring a RESTRICT action causes SQLite to return an error immediately...
Read more >
sqlite3 "foreign key constraint failed" - Stack Overflow
Table B has rows whose foreign key references the primary key value of the Table A row you are trying to delete so...
Read more >
Validations & Constraints - Sequelize
In this tutorial you will learn how to setup validations and constraints for your models in Sequelize.
Read more >
The Comprehensive Sequelize Cheatsheet
Timestamps; Database Synchronization; Expansion of Models; Indexes ... creation ModelName.sync({ force: true }); // this will drop the table ...
Read more >
Piccolo - Release 0.103.0 Daniel Townsend
A piccolo.sqlite file will get created in the current directory. ... tables will be dropped in the correct order based on their foreign...
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