RoR:如何针对多个数据库测试我的应用程序?

发布于 2024-10-22 06:11:26 字数 166 浏览 1 评论 0原文

我开始在 Heroku 上部署最新的 RoR 应用程序,这要求我开始使用 PostgreSQL——我之前一直使用 SQLite 和 MySQL。我想要一种非常简单的方法来持续对所有三个数据库进行红/绿测试,以确保我在开发过程中不会破坏任何东西。

有什么好的方法可以做到这一点?

I started deploying my latest RoR app on Heroku, which required me to start using PostgreSQL -- I'd previously been using SQLite and MySQL. I wanted a dead-simple way to continually do red/green testing against all three databases to make sure I didn't break anything in the heat of development.

What's a good way to do this?

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

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

发布评论

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

评论(1

伪心 2024-10-29 06:11:26

@awendt 善意地指出我可以回答我自己的问题。

事实证明食谱相当简单。秘诀是使用环境变量来告诉 Rails 您要使用哪个数据库。

1. 修改文件

config/database.yml 中,包含如下 ERB 结构:

test:
<% if (ENV["RAILS_DB"] == "PostgreSQL") %>
  adapter: postgresql
  encoding: unicode
  database: bd_test
  pool: 5
  username: <%= ENV['POSTGRESQL_USERNAME'] || 'root' %>
  password: <%= ENV['POSTGRESQL_PASSWORD'] || '' %>
<% elsif (ENV["RAILS_DB"] == "MySQL") %>
  adapter: mysql
  encoding: utf8
  reconnect: false
  database: bd_test
  pool: 5
  username: <%= ENV['MYSQL_USERNAME'] || 'root' %>
  password: <%= ENV['MYSQL_PASSWORD'] || '' %>
  socket: <%= ENV['MYSQL_SOCKET'] || '/tmp/mysql.sock' %>
<% else %>
  # default to SQLite
  adapter: sqlite3
  database: db/test.sqlite3
  pool: 5
  timeout: 5000
<% end %>

注 1:我仅在测试环境中展示它。事实上,这是我修改的唯一一个,因为(据说)它提供了足够的覆盖范围来告诉我是否所有三个数据库都得到正确支持。

注 2:您不需要使用环境变量来设置用户名和密码——这正是我更喜欢做的事情,因为它可以避免在经常查看的文件中暴露密码。

同样,按如下方式扩展 Gemfile(请注意,您的版本号可能会有所不同):

source 'http://rubygems.org'
gem 'rails', '3.0.3'
case ENV["RAILS_DB"]
when "PostgreSQL"
  gem 'pg', '0.10.0'
when "MySQL"
  gem 'mysql2'
else
  gem 'sqlite3', '1.3.3'
  gem 'sqlite3-ruby', '1.3.3', :require => 'sqlite3'
end
...

2. 在代码中添加条件

尽管 Rails 开发团队尽了最大努力,但仍有一些地方 ActiveRecord 构造不兼容所有类型的数据库。在这些情况下,您可以在 ActiveRecord::Base.connection.adapter_name 上调整代码。以下是我的一个迁移文件中的示例:

file: migrate/20110129023453_create_cached_web_pages.rb

def self.up
  create_table :cached_web_pages do |t|
    t.string    :key             
    if ActiveRecord::Base.connection.adapter_name == "PostgreSQL"
      t.binary    :value
    else
      t.binary    :value, :limit => 16777215
    end
  end
end
...

3. 运行和测试

您现在可以通过设置 RAILS_DB 环境变量来选择数据库,但有一个问题:您有每次运行bundle install以从 Gemfile 设置适当的数据库适配器。幸运的是,这正是测试代码的作用。因此,例如,我可以在两个窗口中运行 rspec 的自动测试:

$ RAILS_DB=SQLite autotest

现在

$ RAILS_DB=PostgreSQL autotest

我可以修改我的文件,如果我在运行过程中损坏了任何东西,自动测试会悄悄地提醒我。

@awendt kindly pointed out that I could answer my own question.

It turns out the recipe is rather simple. The secret is to use a environment variable to tell Rails which db you want to use.

1. Modifying your files

In config/database.yml, include ERB constructs like this:

test:
<% if (ENV["RAILS_DB"] == "PostgreSQL") %>
  adapter: postgresql
  encoding: unicode
  database: bd_test
  pool: 5
  username: <%= ENV['POSTGRESQL_USERNAME'] || 'root' %>
  password: <%= ENV['POSTGRESQL_PASSWORD'] || '' %>
<% elsif (ENV["RAILS_DB"] == "MySQL") %>
  adapter: mysql
  encoding: utf8
  reconnect: false
  database: bd_test
  pool: 5
  username: <%= ENV['MYSQL_USERNAME'] || 'root' %>
  password: <%= ENV['MYSQL_PASSWORD'] || '' %>
  socket: <%= ENV['MYSQL_SOCKET'] || '/tmp/mysql.sock' %>
<% else %>
  # default to SQLite
  adapter: sqlite3
  database: db/test.sqlite3
  pool: 5
  timeout: 5000
<% end %>

Note 1: I've only shown it for the test environment. In fact, that's the only one I've modified, since (supposedly) it provides enough coverage to tell me if all three databases are properly supported.

Note 2: You don't need to use environment variables to set username and password -- that's just something I prefer to do since it avoids exposing passwords in a commonly viewed file.

Similarly, extend Gemfile as follows (note that your version numbers may vary):

source 'http://rubygems.org'
gem 'rails', '3.0.3'
case ENV["RAILS_DB"]
when "PostgreSQL"
  gem 'pg', '0.10.0'
when "MySQL"
  gem 'mysql2'
else
  gem 'sqlite3', '1.3.3'
  gem 'sqlite3-ruby', '1.3.3', :require => 'sqlite3'
end
...

2. Add conditions to your code

Despite the best efforts of the Rails development team, there are a few spots where ActiveRecord constructs aren't compatible across all flavors of database. In these cases, you can condition your code on ActiveRecord::Base.connection.adapter_name. Here's an example from one of my migration files:

file: migrate/20110129023453_create_cached_web_pages.rb

def self.up
  create_table :cached_web_pages do |t|
    t.string    :key             
    if ActiveRecord::Base.connection.adapter_name == "PostgreSQL"
      t.binary    :value
    else
      t.binary    :value, :limit => 16777215
    end
  end
end
...

3. Running and testing

You can now select a database simply by setting the RAILS_DB environment variable, but there's a catch: you have to run bundle install each time to set up the appropriate database adaptor from the Gemfile. Fortunately, that's exactly what the test code does. So, for example, I can run rspec's autotest in two windows:

$ RAILS_DB=SQLite autotest

and

$ RAILS_DB=PostgreSQL autotest

Now I can hack away at my files and autotest will quietly alert me if I've broken anything as I go along.

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