2015-12-24 1 views
4

У меня проблемы с использованием database cleaner с sequel и ограничениями внешнего ключа sqlite. В частности, я использую стратегию :truncation с интеграционными тестами Capybara.Проблемы с внешним ключом с использованием сиквела и очистителя базы данных

Для данной выборки схемы:

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) 
); 

И сиквел модели:

class User < Sequel::Model 
    many_to_many :events 
end 

class Event < Sequel::Model 
    many_to_many :users 
end 

Running следующие:

# 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 

вызвавший ошибку

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

я могу обойти эту проблему путем изменения моего перед заявлением, чтобы отключить foreign_keys Pragma:

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

(или не используя FOREIGN KEY в моих таблицах), но это кажется неправильным, так как я хочу, преимущества, внешние ключи ограничения - или, по крайней мере, я так думаю;).

Это фундаментальное непонимание того, как использовать ограничения внешнего ключа, или есть лучший способ сделать это?

ответ

0

Прошло почти два года, и я отказался от попытки решить эту чистоту T_T.

Я испытал случайный FOREIGN KEY constraint failed вопросов во время недавнего обновления sequel. Чтобы решить эту проблему, я переключился с DatabaseCleaner.strategy = :truncation на DatabaseCleaner.strategy = :deletion.

Существует thorough analysis of the benefits/costs of :truncate versus :delete, и ответ (по крайней мере, для postgres) равен . До сих пор :delete, по-видимому, немного быстрее для моего небольшого набора данных тестирования.

Смежные вопросы