【问题标题】:Migrations with a Rails multiple database configuration使用 Rails 多数据库配置进行迁移
【发布时间】:2011-11-05 11:42:36
【问题描述】:

我正在开发一个 Rails 应用程序,我将在其中使用 2 个不同的数据库。即一个用于存储用户凭据,另一个用于存储其他类型的数据。 我已经为每个环境设置了我的 database.yml 文件以接受 2 个不同的数据库。它看起来像这样:

<% %w(development test production).each do |env| %>
data_<%= env %>:
  adapter: sqlite3
  database: db/data/<%= env %>.sqlite3
  pool: 5
  timeout: 5000

users_<%= env %>:
  adapter: sqlite3
  database: db/users/<%= env %>.sqlite3
  pool: 5
  timeout: 5000
<% end %>

我还创建了 2 级模型,每个数据库连接一个,即:

class UsersBase < ActiveRecord::Base
  establish_connection "users_#{RAILS_ENV}"
end

和

class DataBase < ActiveRecord::Base
  establish_connection "data_#{RAILS_ENV}"
end

我在生成模型时遇到了一些问题,因为它找不到标准的“开发”数据库,但我通过运行生成模型并将 --parent 选项设置为适当的类解决了这个问题。

但是,现在我在尝试运行 rake db:migrate 时遇到了问题。 rake 任务没有找到默认的开发数据库(按照惯例,它应该在 database.yml 中命名为 development)。我的问题是是否有可能以某种方式将其作为参数提供给 rake 任务,或者甚至更好地在配置脚本中的某处向 Rails 发出信号,告知有 2 个数据库,或者开发数据库的默认名称已更改?

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 activerecord rails-migrations


    【解决方案1】:

    您正在定义这些数据库:

    1. data_development
    2. users_development
    3. data_test
    4. users_test
    5. data_production
    6. users_production

    Rails 首先寻找与环境名称(开发、测试、生产)匹配的数据库定义。对于您的数据数据库,只需使用这些名称即可迁移数据数据库。

    试试

    <% %w(development test production).each do |env| %>
      <%= env %>:
      adapter: sqlite3
      database: db/data/<%= env %>.sqlite3
      pool: 5
      timeout: 5000
    
    users_<%= env %>:
      adapter: sqlite3
      database: db/users/<%= env %>.sqlite3
      pool: 5
      timeout: 5000
    <% end %>
    

    所有“data_X” dbs 将只携带环境的名称。这是 Rails 所期望的,因此迁移将对它们起作用。

    尽管在迁移用户数据库方面,这可能会让您感到冷漠。我不认为 Rails 迁移打算以这种方式使用 - 在一个环境中迁移 2 个数据库。

    也就是说,我会尝试一下。这是与上面的 database.yml 更改保持一致所需的模型更改:

    class DataBase < ActiveRecord::Base
    end
    

    事实上,您可以完全取消 DataBase,只需让以前的 DataBase 模型直接扩展 ActiveRecord::Base。

    如果你尝试一下,有兴趣看看你会发现什么。

    【讨论】:

    • 事后诸葛亮.. 为什么这个数据库会分裂?一个管理 2 个独立数据库的应用程序是可能的,但步骤超出了“Rails 约定”的范围。当然这是可能的,但并非没有痛苦和维护头痛的惩罚。老实说,如果我的一位开发人员提出这种方案,我会把他们送回绘图板。
    • 问题是 Rails 应用程序是一个更大的系统的一部分,它涉及其他组件,如爬虫、数据分析、编译统计数据的系统等......用户数据库实际上将通过所有共享系统的组件(即可以在 Rails Web 应用程序之外创建用户)和“数据”数据库将仅用于提供 Web 端内容。通过这种方式,我非常希望将它们分开......
    • 尽管以某种方式从 Web 应用程序数据库中的用户数据库表中复制用户数据的相关部分并将其用于登录和注销可能会更好 - 但是在这种情况下我会有同步问题...
    • 在我看来,用户数据库应该是这些系统使用的服务。 API 之类的。如果用户数据库只捕获身份、身份验证和更多类似角色的信息,我将提供一个 ldap 服务供所有人查阅。您为自己设定的道路会带来永远不会消失的痛苦。
    【解决方案2】:

    我为这个用例写了pg_migrate。您可以使用此项目在 Rails 应用程序之外定义模式,但仍将其与 Rails 应用程序本地集成(pg_migrate 可以输出“模式 gem”,这只是您的模式和用于迁移它的类/cli)。使用它确实意味着将 db:migrate 作为开发过程的一部分。

    网络应用不一定“拥有”架构。此外,您可以使用多种语言进行编程。

    不过,仅限 Postgres。

    【讨论】:

      猜你喜欢
      • 2016-10-15
      • 1970-01-01
      • 2020-06-20
      • 2017-02-10
      • 2019-12-02
      • 2011-10-12
      • 1970-01-01
      • 2020-04-21
      • 1970-01-01
      相关资源
      最近更新 更多