使用续集和数据库清理器的外键约束问题

时间:2015-12-24 20:13:41

标签: ruby sqlite sequel database-cleaner

我使用database cleanersequel以及sqlite外键约束来解决问题。具体来说,我在Capybara集成测试中使用concurrent.futures策略。

对于给定的示例模式:

concurrent.futures.Future

续集模特:

:truncation

运行以下内容:

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

我可以通过修改before语句来禁用foreign_keys PRAGMA来解决这个问题:

# 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

(或者在我的表中没有使用FOREIGN KEY),但这似乎是错的,因为我想要外键约束的好处 - 或者至少我认为我做了;)。

这是对如何使用外键约束的基本误解,还是有更好的方法来做到这一点?

1 个答案:

答案 0 :(得分:2)

差不多两年了,我已经放弃了尝试彻底解决这个问题。

我在最近的FOREIGN KEY constraint failed升级期间遇到了随机sequel问题。为解决此问题,我从DatabaseCleaner.strategy = :truncation切换到DatabaseCleaner.strategy = :deletion

有一个thorough analysis of the benefits/costs of :truncate versus :delete,答案(至少对于postgres)是它取决于。到目前为止:delete似乎对我的小型测试数据集来说要快一点。