【问题标题】:Rails Unit Testing with MyISAM Tables使用 MyISAM 表进行 Rails 单元测试
【发布时间】:2011-02-06 15:41:30
【问题描述】:

我有一个应用程序需要在几个表上使用 MyISAM,但其余的是传统的 InnoDB 类型。应用程序本身并不关心应用于这些记录的事务,但性能是一个问题。

Rails 测试环境假定使用的引擎是事务性的,所以当从 schema.rb 生成测试数据库时,它会使用相同的引擎导入。是否可以以简单的方式覆盖此行为?

我采取了一种可怕的技巧,通过将其附加到 test_helper.rb 来确保表是正确的类型:

(ActiveRecord::Base.connection.select_values("SHOW TABLES") - %w[ schema_info ]).each do |table_name|
  ActiveRecord::Base.connection.execute("ALTER TABLE `#{table_name}` ENGINE=InnoDB")
end

有没有更好的方法让 MyISAM 支持的模型可测试?

【问题讨论】:

  • 同样的问题 - rake 规范将从不包含引擎选项的 schema.rb 文件重新创建测试数据库。最好的解决方案可能是修补 Rails 的模式编写部分,以将 :options 参数添加到 create_table() ,只要它不是默认值。

标签: mysql ruby-on-rails unit-testing myisam


【解决方案1】:

您可以编辑您的 schema.rb 并修改 create_table 调用以包含以下标志,如下所示:

create_table(:suppliers, :options => 'ENGINE=InnoDB DEFAULT CHARSET=utf8')

创建迁移时,请尝试将其添加到迁移中。我不知道当你运行 rake db:schema:dump 时这是否会坚持下去。鉴于您的经验,测试环境似乎没有正确复制开发环境,它可能不会:(

更多关于 create_table 选项的信息在这里:

http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html#M001901

【讨论】:

  • 修改 schema.rb 是短期修复,因为下一次迁移将覆盖所做的任何更改。我希望能找到一种更持久、更少黑客攻击的方法,但似乎还不实用。
【解决方案2】:

你可以设置

self.use_transactional_fixtures = false

在 test_helper.rb 中

【讨论】:

    【解决方案3】:

    您可以将此添加到application.rb:

    config.active_record.schema_format = :sql
    

    这样,test db 将不会对命令rake db:test:prepare 有任何问题。在迁移文件中,无需重新创建表(如果您需要将现有的 InnoDB 表更改为 MyISAM),您只需将其添加到 up 方法:

    execute("ALTER TABLE your_table ENGINE=MyISAM")
    

    【讨论】:

      【解决方案4】:

      您可以添加此 SchemaDumper monkeypatch 以在您的 schema.rb 中显式添加引擎

      https://gist.github.com/1374003

      这是来自 Rails 2.3.14 的猴子补丁,因此 Rails 3 无法保证

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-29
        • 1970-01-01
        相关资源
        最近更新 更多