Open lukkry opened 10 years ago
It works if I set default_shard earlier
$ be rails c
Loading development environment (Rails 3.2.14)
1.9.3-p429 :001 > ActiveRecord::Base.default_shard = 1
=> 1
1.9.3-p429 :002 > ActiveRecord::Base.on_shard(1){ Project.where(:id => 1) }
Project Load (0.3ms) SELECT `projects`.* FROM `projects` WHERE `projects`.`id` = 1
=> []
What's probably happening here is that the call to 'where' is returning an active relation object, ie a "promise" that is then evaluated outside the block (probably when irb calls "to_s") on it. Unfortunately, at that point we've already switched off the shard again.
On Sep 2, 2013, at 1:13 PM, Lukasz Krystkowiak notifications@github.com wrote:
ActiveRecordShards tries to read from not sharded database when calling
ActiveRecord::Base.on_shard(1){ Project.where(:id => 1) } Steps to reproduce:
create a new rails 3.2.14 app add active_record_shards to Gemfile create database.yml development: adapter: mysql2 encoding: utf8 database: mango pool: 5 host: 127.0.0.1 username: root password: slave: database: mango_slave shards: 1: database: mango_shard0 slave: database: mango_shard0_slave 2: database: mango_shard1 slave: database: mango_shard1_slave $ bundle exec rails g model Project name:string class CreateProjects < ActiveRecord::Migration shard :all
def change create_table :projects do |t| t.string :name
t.timestamps end
end end $ bundle exec rake db:migrate $ bundle exec rails c 1.9.3-p429 :008 > ActiveRecord::Base.on_shard(1){ Project.connection.current_database } (2.5ms) SELECT DATABASE() as db => "mango_shard0" 1.9.3-p429 :006 > ActiveRecord::Base.on_shard(1){ Project.all } Project Load (0.3ms) SELECT
projects
.* FROMprojects
=> [] 1.9.3-p429 :001 > ActiveRecord::Base.on_shard(1){ Project.where(:id => 1) } Project Load (0.3ms) SELECTprojects
.* FROMprojects
WHEREprojects
.id
= 1 ActiveRecord::StatementInvalid: Mysql2::Error: Table 'mango.projects' doesn't exist: SELECTprojects
.* FROMprojects
WHEREprojects
.id
= 1 Am I missing something obvious here?— Reply to this email directly or view it on GitHub.
You're right, it works as expected when it's evaluated inside the block
1.9.3-p429 :001 > ActiveRecord::Base.on_shard(1){ Project.where(:id => 1).first }
Project Load (0.3ms) SELECT `projects`.* FROM `projects` WHERE `projects`.`id` = 1 LIMIT 1
=> nil
re-opening, since this is very violiating of principle of least surprises -- any ideas on what it would take to stash the shard-selection alongside the activerelation promise object and switch in and out of the shard for the duration of the query?
Something like what I did for the old ticket archive. RelationFromArchive
in https://github.com/zendesk/zendesk/blob/master/lib/archive.rb
ActiveRecordShards tries to read from not sharded database when calling
Steps to reproduce:
$ bundle exec rails g model Project name:string
$ bundle exec rake db:migrate
$ bundle exec rails c
Am I missing something obvious here?