生产环境下Rails控制台无法访问不同的数据库。

6

我有一个名为database.yml的文件,其内容如下:

default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  socket: /var/run/mysqld/mysql.sock

development:
  tp:
    <<: *default
    database: tp
    host: xxx.xxx.xxx.xxx
    username: test
    password: test
    migrations_paths: db/tp_migrate
  mi:
    <<: *default
    database: mi
    host: xxx.xxx.xxx.xxx
    username: test
    password: test
    migrations_paths: db/mi_migrate


production:
  tp:
    <<: *default
    database: tp
    host: xxx.xxx.xxx.xxx
    username: test
    password: test
    migrations_paths: db/tp_migrate
  mi:
    <<: *default
    database: mi
    host: xxx.xxx.xxx.xxx
    username: test
    password: test
    migrations_paths: db/mi_migrate

tp数据库中有一张名为servant的表。 mi数据库中有一张名为landlord的表。 我有以下模型:

application_record.rb

class ApplicationRecord < ActiveRecord::Base
  self.abstract_class = true
  connects_to database: { writing: :mi, reading: :mi }
end

tp_base.rb

class TpBase < ActiveRecord::Base
  self.abstract_class = true
  connects_to database: { writing: :tp, reading: :tp }
end

landlord.rb

class Landlord < ApplicationRecord
end

servant.rb

class servant < TpBase
end

当我打开开发控制台时,我可以访问两个表,即服务员和房东。

开发控制台

raj@Raj:~/Desktop/testing_app(development)$ RAILS_ENV=development rails c
Running via Spring preloader in process 51558
Loading development environment (Rails 6.0.4.1)
2.6.3 :001 > Landlord.first
  Landlord Load (263.3ms)  SELECT `landlord`.* FROM `landlord` ORDER BY `landlord`.`id` ASC LIMIT 1
 => #<Landlord id: 44> 
2.6.3 :002 > Servant.first
  Servant Load (276.7ms)  SELECT `servant`.* FROM `servant` ORDER BY `servant`.`id` ASC LIMIT 1
 => #<servant id: 1> 

当我打开生产控制台时,我只能访问服务员表,但无法访问房东表。

生产控制台

raj@Raj:~/Desktop/testing_app(development)$ RAILS_ENV=production rails c
Loading production environment (Rails 6.0.4.1)
2.6.3 :001 > Landlord.first
  Landlord Load (248.7ms)  SELECT `landlord`.* FROM `landlord` ORDER BY `landlord`.`id` ASC LIMIT 1
Traceback (most recent call last):
        1: from (irb):1
ActiveRecord::StatementInvalid (Mysql2::Error: Table 'tp.landlord' doesn't exist)
2.6.3 :002 > Servant.first
  Servant Load (265.9ms)  SELECT `servant`.* FROM `servant` ORDER BY `servant`.`id` ASC LIMIT 1
 => #<Servant id: 1> 

但是当我手动在生产控制台中建立与数据库的连接时,只能访问landlord表。

手动连接

ActiveRecord::Base.establish_connection(:mi).connection

raj@Raj:~/Desktop/testing_app(development)$ RAILS_ENV=production rails c
Loading production environment (Rails 6.0.4.1)
2.6.3 :001 > Landlord.first
  Landlord Load (264.9ms)  SELECT `landlord`.* FROM `landlord` ORDER BY `landlord`.`id` ASC LIMIT 1
Traceback (most recent call last):
        1: from (irb):1
ActiveRecord::StatementInvalid (Mysql2::Error: Table 'tp.landlord' doesn't exist)
2.6.3 :002 > Servant.first
  Servant Load (263.6ms)  SELECT `servant`.* FROM `servant` ORDER BY `servant`.`id` ASC LIMIT 1
 => #<Servant id: 0, name: "", phone: "", company: "", active: "\x00", has_license: "\x01", license_class: "", default_truck_id: 8, gps_color: "00FFFF", gps_device_id: nil, rate_per_hour: 0.0, rate_per_km: 0.0, rate_per_drop: 0.0, rate_per_run: 0.0, exclude_accounting: "\x00"> 
2.6.3 :003 > ActiveRecord::Base.establish_connection(:mi).connection
2.6.3 :004 > Landlord.first
  Landlord Load (243.3ms)  SELECT `landlord`.* FROM `landlord` ORDER BY `landlord`.`id` ASC LIMIT 1
 => #<Landlord id: 44>
 2.6.3 :006 > Servant.first
  Servant Load (243.7ms)  SELECT `servant`.* FROM `servant` ORDER BY `servant`.`id` ASC LIMIT 1
 => #<Servant id: 1> 

我的问题是:为什么在生产模式下控制台默认不加载两个数据库?我是否做错了什么,或者这是预期的行为而没有任何问题?


tp数据库有一张名为servant的表。mi数据库有一张名为landlord的表。我猜你已经确认了这在开发和生产环境中都是一样的。 - Thomas Koppensteiner
1个回答

6

看起来你把2个概念混淆了:复制和分片。当使用复制时,你需要使用connects_to database: { writing: :tp, reading: :tp }其中writing:为主服务器,reading:为只读副本。如果你没有副本,则只需要指定writing:

根据你的代码,你想要分片。在这种情况下,你应该使用connects_to shards: { }

例如:

class ApplicationRecord < ActiveRecord::Base
  self.abstract_class = true
  connects_to shards: { 
    default: { writing: :mi }
  }
end


class TpBase < ActiveRecord::Base
  self.abstract_class = true
  connects_to shards: { 
    shard: { writing: :tp }
  }
end

更多信息请参考:https://edgeguides.rubyonrails.org/active_record_multiple_databases.html#horizontal-sharding 不确定这是否解决了你的问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接