Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Foreign Key constraint issues using sequel and database cleaner

I am running into issues using database cleaner with sequel and sqlite foreign key constraints. Specifically, I am using the :truncation strategy with Capybara integration tests.

For the given sample schema:

CREATE TABLE users(id INTEGER PRIMARY KEY, name TEXT);
CREATE TABLE events(id INTEGER PRIMARY KEY, title TEXT);

CREATE TABLE events_users(
  user_id INTEGER,
  event_id INTEGER,

  FOREIGN KEY(user_id) REFERENCES users(id),
  FOREIGN KEY(event_id) REFERENCES events(id)
);

And sequel models:

class User < Sequel::Model
  many_to_many :events
end

class Event < Sequel::Model
  many_to_many :users
end

Running the following:

# normally this would be run in
# an rspec before(:each) for my :feature specs
DatabaseCleaner.start
DatabaseCleaner.strategy = :truncation

bob = User.create(name: "bob")
sally = User.create(name: "sally")
event = Event.create(title: "Everyone's invited")
event.users << [bob, sally]

DatabaseCleaner.clean

Results in an error

SQLite3::ConstraintException: FOREIGN KEY constraint failed (Sequel::ForeignKeyConstraintViolation)

I can get around this by altering my before statement to disable the foreign_keys PRAGMA:

DB.foreign_keys = false
DatabaseCleaner.start
DatabaseCleaner.strategy = :truncation

(or not using FOREIGN KEY in my tables), but that seems wrong since I want the benefits that foreign keys constraints — or at least I think I do ;).

Is this a fundamental misunderstanding of how to use foreign key constraints, or is there a better way to do this?

like image 460
Nick Tomlin Avatar asked Dec 24 '15 20:12

Nick Tomlin


People also ask

How do I fix foreign key constraint failure?

The error message itself showing there is a foreign key constraint error, which means you are deleting a parent table where the child table contains the Primary table identifier as a foreign key. To avoid this error, you need to delete child table records first and after that the parent table record.

How can delete foreign key constraint in SQL Server using query?

To delete a foreign key constraint In Object Explorer, expand the table with the constraint and then expand Keys. Right-click the constraint and then click Delete. In the Delete Object dialog box, click OK.

What problems do foreign keys introduced?

A foreign key might point to data that no longer exists, or the foreign key's data type doesn't match the primary key data type, eroding referential integrity. Referential integrity can also be corrupted if the foreign key doesn't reference all the data from the primary key.

Why can't I add a foreign key constraint?

The usual cause are generally a mismatch in the type of the column of the primary table and the foreign table. It can also be a mismatch in the Engine type of two tables i.e. MyISAM or InnoDB. Datatype both columns should have same datatype. int(11) on one table and smallint(5) on another will cause problem.


1 Answers

It's been almost two years and I've given up attempting to solve this cleanly T_T.

I experienced random FOREIGN KEY constraint failed issues during a recent sequel upgrade. To resolve this, I switched from DatabaseCleaner.strategy = :truncation to DatabaseCleaner.strategy = :deletion.

There's been a thorough analysis of the benefits/costs of :truncate versus :delete and the answer (at least for postgres) is it depends. So far :delete seems to be a little faster for my small testing data set.

like image 153
Nick Tomlin Avatar answered Oct 23 '22 19:10

Nick Tomlin