Rails 3 不能在没有 InnoDB 的情况下以 MySQL MyISAM 模式运行吗?

发布于 2024-12-23 16:20:32 字数 723 浏览 1 评论 0原文

我有一个禁用 InnoDB 运行的 MySQL 服务器(出于性能原因),使用此设置我似乎无法使用 Rails 3(使用 mysql2 适配器)。

这是我的测试迁移:

class CreateTxts < ActiveRecord::Migration
  def change
    create_table(:txts, :options => 'ENGINE=MyISAM') do |t|
      t.timestamps
    end
  end
end

这是错误:

>rake db:migrate
rake aborted!
Mysql2::Error: Unknown storage engine 'InnoDB': CREATE TABLE `schema_migrations`
(`version` varchar(255) NOT NULL) ENGINE=InnoDB

尝试了描述的解决方法 这里,但它似乎也不起作用(我确实将 MysqlAdapter 修改为 Mysql2Adapter 以匹配我的设置)。

抱歉,我是 Rails 新手。任何帮助将不胜感激:o

I have a MySQL server running with InnoDB disabled (for reasons of performance), with this setup I can't seem to be able to use Rails 3 (with the mysql2 adapter).

Here's my test migration:

class CreateTxts < ActiveRecord::Migration
  def change
    create_table(:txts, :options => 'ENGINE=MyISAM') do |t|
      t.timestamps
    end
  end
end

And here's the error:

>rake db:migrate
rake aborted!
Mysql2::Error: Unknown storage engine 'InnoDB': CREATE TABLE `schema_migrations`
(`version` varchar(255) NOT NULL) ENGINE=InnoDB

Tried the workaround described here, but it doesn't seem to work either (I did modify MysqlAdapter to Mysql2Adapter to match my setup).

Sorry I'm a newb in Rails. Any help will be much appreciated :o

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

夏雨凉 2024-12-30 16:20:32

我要回答我自己的问题。这是我最终得到的 environment.rb 补丁,它可以与本机 mysql 驱动程序以及 JRuby/JDBC-mysql 一起使用:

# Load the rails application
require File.expand_path('../application', __FILE__)

# Patch Mysql adapter to default to MyISAM instead of InnoDB
require 'active_record/connection_adapters/mysql_adapter'
module ActiveRecord
  module ConnectionAdapters
    class MysqlAdapter
      def create_table(table_name, options = {}) #:nodoc:
        super(table_name, options.reverse_merge(:options => "ENGINE=MyISAM"))
      end
    end
  end
end

# Initialize the rails application
.....

rake db:migrate 现在成功并创建了所有包括 TYPE=MyISAM 的 schema_migrations 表。

注意:对于 mysql2 适配器,将 mysql_adapter 重命名为 mysql2_adapter,将 MysqlAdapter 重命名为 Mysql2Adapter。

Going to answer my own question. Here's a patch for environment.rb I ended up with that works with the native mysql driver as well as JRuby/JDBC-mysql:

# Load the rails application
require File.expand_path('../application', __FILE__)

# Patch Mysql adapter to default to MyISAM instead of InnoDB
require 'active_record/connection_adapters/mysql_adapter'
module ActiveRecord
  module ConnectionAdapters
    class MysqlAdapter
      def create_table(table_name, options = {}) #:nodoc:
        super(table_name, options.reverse_merge(:options => "ENGINE=MyISAM"))
      end
    end
  end
end

# Initialize the rails application
.....

rake db:migrate now succeeds and creates all tables including schema_migrations with TYPE=MyISAM.

Note: For mysql2 adapter, rename mysql_adapter to mysql2_adapter and MysqlAdapter to Mysql2Adapter.

我的奇迹 2024-12-30 16:20:32

尝试在不指定所使用的引擎类型的情况下创建表

class CreateTxts < ActiveRecord::Migration
  def change
    create_table(:txts) do |t|
      t.timestamps
    end
  end
end

,然后在 mysql cli 中输入以下内容

ALTER TABLE txts ENGINE = MYISAM

希望有帮助

Try creating the table without specifying the type of engine being used like this

class CreateTxts < ActiveRecord::Migration
  def change
    create_table(:txts) do |t|
      t.timestamps
    end
  end
end

and then in mysql cli, type this

ALTER TABLE txts ENGINE = MYISAM

hope it helps

薄荷梦 2024-12-30 16:20:32

该错误来自于创建 schema_migrations 表(rails 使用该表来跟踪已运行的迁移)而不是您的表。您可以自己创建该表(使用名为 version 的单个 varchar(255) 列,并在其上有索引)。

如果您最终覆盖了 create_table 方法,则需要保留该方法的签名 - 您将忽略它生成的块。我会尝试类似的东西

def create_table(name, options={})
  super(name, options.merge(...)) {|t| yield t}
end

The error is coming from creating the schema_migrations table (which rails uses to track which migrations have been run) rather than your table. You could create that table yourself (with a single varchar(255) column called version with an index on it).

If you do end up overwriting the create_table method, you need to preserve the method's signature - you're ignoring the block that it yields. I'd try something like

def create_table(name, options={})
  super(name, options.merge(...)) {|t| yield t}
end
宫墨修音 2024-12-30 16:20:32

@rustyx 不错!这是我稍微调整过的猴子补丁,因此可以从 /config/database.yml 配置中设置引擎:

&而不是在 /config/environment.rb 中 设置>,我将代码放入初始化程序中,例如:/config/initializers/mysql2adapter_default_engine.rb

为了简洁起见,可以这样:

require 'active_record/connection_adapters/abstract_mysql_adapter'

class ActiveRecord::ConnectionAdapters::Mysql2Adapter < ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter
  def create_table(table_name, options = {}) #:nodoc:
    super(table_name,  @config[:engine].nil? ? options : options.reverse_merge(:options => "ENGINE="+@config[:engine]))
  end
end

或者为了更清楚:

require 'active_record/connection_adapters/abstract_mysql_adapter'

module ActiveRecord
  module ConnectionAdapters
    class Mysql2Adapter < AbstractMysqlAdapter
      def create_table(table_name, options = {}) #:nodoc:
        super(table_name,  @config[:engine].nil? ? options : options.reverse_merge(:options => "ENGINE="+@config[:engine]))
      end
    end
  end
end

然后在/config/database.yml中我们可以有这样的东西:

production:
  adapter:  mysql2
  encoding: utf8
  database: ooook
  username: ooook
  password: ooook
  host:     ooook.tld
  port:     3306
  pool:     5
  timeout:  5000
  engine:   MyISAM   

如果没有指定engine,那么mysql2适配器将使用默认值(InnoDB或其他)。

@rustyx nice one! &here's my slightly tweaked monkey-patch so the engine can be set from within the /config/database.yml configuration:

&Rather than in /config/environment.rb, i put the codes into an initializer, Eg: /config/initializers/mysql2adapter_default_engine.rb.

Either this for brevity:

require 'active_record/connection_adapters/abstract_mysql_adapter'

class ActiveRecord::ConnectionAdapters::Mysql2Adapter < ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter
  def create_table(table_name, options = {}) #:nodoc:
    super(table_name,  @config[:engine].nil? ? options : options.reverse_merge(:options => "ENGINE="+@config[:engine]))
  end
end

or this for more clarity:

require 'active_record/connection_adapters/abstract_mysql_adapter'

module ActiveRecord
  module ConnectionAdapters
    class Mysql2Adapter < AbstractMysqlAdapter
      def create_table(table_name, options = {}) #:nodoc:
        super(table_name,  @config[:engine].nil? ? options : options.reverse_merge(:options => "ENGINE="+@config[:engine]))
      end
    end
  end
end

Then in /config/database.yml we can have something like this:

production:
  adapter:  mysql2
  encoding: utf8
  database: ooook
  username: ooook
  password: ooook
  host:     ooook.tld
  port:     3306
  pool:     5
  timeout:  5000
  engine:   MyISAM   

If no engine is specified then the mysql2 adapter will use the default (InnoDB or whatever).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文