Rails 如何让不同的 model 关联不同类型的数据库?

lengcb · 2018年04月04日 · 最后由 lengcb 回复于 2018年04月04日 · 1800 次阅读

如:OldUser 关联 mysql 数据库,NewUser 关联 pgsql 数据库

公司以前的项目需要重构,原数据库用的 mysql,版本很古老了,里面一些 json 格式的数据都是序列化存的 text 类型,我不喜欢。项目以前的类的设计都有问题,项目已经上线了。现在我想用 pgsql,新建的类跟 pgsql 关联,创建 model 时,生成的表存到 pgsql 里。该如何实现呢?表述不是很清楚,请担待。

先搞清楚你的想法是否能实现,技术上搞定了其他人不配合也没办法。

https://groups.google.com/forum/#! topic/sequel-talk/kTIXICM2DyE

这里面其实有两件事情。首先是重新整理数据库结构以及相关的代码,其次是换数据库,哪件先做都可以,但一次只应该做其中的一件。

同时使用两个数据库纯粹增加复杂性。

qiumaoyuan 回复

嗯嗯,明白。现在数据库结构整理好了,要重新创建新的 model,新的 model 字段属性与关系都与旧版不一样,想让新建的 model 都关联 pgsql,创建好 model,执行迁移,在 pgsql 中生成表,而不是在 mysql 中生成表。

你这个其实就是一个 Rails 项目使用两个不同的数据库。可以参考一楼的例子。当然 Rails6.0 也开始支持这样做了https://github.com/rails/rails/pull/32274

charles 回复

我重新创建的 model 跟旧的不一样,像创建完 model,执行迁移,在 pgsql 中生成表。就是说,我创建好 model 后,执行迁移时可以指定在哪个数据库生成对应的表。

nouse 回复

嗯嗯,确实有这个问题。其实我们公司不是一家做软件的公司。公司有个产品,让我长期维护,我想着就一点点的慢慢重构,慢慢改版,其实想着重新建一个项目的。结果遇到这么个问题,就想着看如何才能在技术上解决这个问题。

charles 回复

database.yml

default: &default
  adapter: mysql2
  encoding: utf8
  pool: 5
  username: root
  password: root
  host:

development:
  <<: *default
  database: old_development

other_development:
  adapter: postgresql
  encoding: unicode
  pool: 20
  username: root
  password: root
  database: otherdb_development

models/other_database.rb

class OtherDatabase < ApplicationRecord
  establish_connection "other_#{RAILS_ENV}"
end

model/demo.rb

class Demo < OtherDatabase
end

demo 的迁移文件

class CreateDemos < ActiveRecord::Migration[5.0]
  def change
    create_table :demos do |t|
      t.jsonb :name
      t.timestamps
    end
  end
end

创建了一个 jsonb 格式的字段,当我执行数据迁移时,发现还是链接的是 mysql 数据库

NoMethodError: undefined method `jsonb' for #<ActiveRecord::ConnectionAdapters::MySQL::TableDefinition:0x007fc6b72018d8>

是我哪里处理的不对吗?

连多个数据库挺容易的,原理大家已经给出了,可用的工具是 multiverse

但问题是,真的需要换数据库吗?uber 数据库就换来换去的 https://eng.uber.com/mysql-migration/

还要考虑这个技术方案,是否可行。假设是分模块迁移,如果模块和模块之间的表有 join 的话,这个方案不行。项目模块划分不清才是最大的问题,模块划分请了,其他的都是小问题。

最后也是最重要的,原有问题到底出在哪?没有具体问题,技术连存在的意义都没有。技术过时,显然不是一个问题。.net 还过时能,但性能吊打 n 多框架。

json 序列化并不是个大问题,除非有查询需要,不喜欢并不是换数据库的充分理由。

我觉得应该新开一个项目,在新的项目里做,然后把老的 url proxy_pass 到新的项目

@tianyu0915 @Rei @yfractal 谢谢!我的一开始的出发点是错的。其实后面纯粹就是想解决这个问题了。其实就是二楼这个链接里描述的问题 https://groups.google.com/forum/#! topic/sequel-talk/kTIXICM2DyE

liukun_lk 回复

是的,但是一直不成功,我讲代码已经贴上去了,能帮我找一下哪里出错吗?

@all 谢谢各位,从这个问题学到很多

lengcb 回复

你的rake db:migrate命令也需要修改的。不然还是会跑到老的数据库上面去执行 migration 的

liukun_lk 回复

嗯嗯,看了一下 multiverse 这个插件的实现。不过发现版本支持有点小问题,rails5.0.1 时,创建迁移文件还是在 db/migrate 下,得手动移到相应目录下。当>=5.0.3 版本时才会在正确的位置生成。还有就是创建 model 时,不会自动生成迁移文件,可能还是我命令的问题。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号