Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"where" doesn't work when on_shard (Rails 3.2) #6

Open
lukkry opened this issue Sep 2, 2013 · 5 comments
Open

"where" doesn't work when on_shard (Rails 3.2) #6

lukkry opened this issue Sep 2, 2013 · 5 comments

Comments

@lukkry
Copy link
Contributor

lukkry commented Sep 2, 2013

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`.* FROM `projects`
 => []
1.9.3-p429 :001 > ActiveRecord::Base.on_shard(1){ Project.where(:id => 1) }
  Project Load (0.3ms)  SELECT `projects`.* FROM `projects` WHERE `projects`.`id` = 1
ActiveRecord::StatementInvalid: Mysql2::Error: Table 'mango.projects' doesn't exist: SELECT `projects`.* FROM `projects`  WHERE `projects`.`id` = 1

Am I missing something obvious here?

@lukkry
Copy link
Contributor Author

lukkry commented Sep 2, 2013

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
 => []

@osheroff
Copy link
Contributor

osheroff commented Sep 2, 2013

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 [email protected] 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.* FROM projects
=> []
1.9.3-p429 :001 > ActiveRecord::Base.on_shard(1){ Project.where(:id => 1) }
Project Load (0.3ms) SELECT projects.* FROM projects WHERE projects.id = 1
ActiveRecord::StatementInvalid: Mysql2::Error: Table 'mango.projects' doesn't exist: SELECT projects.* FROM projects WHERE projects.id = 1
Am I missing something obvious here?


Reply to this email directly or view it on GitHub.

@lukkry
Copy link
Contributor Author

lukkry commented Sep 3, 2013

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

@lukkry lukkry closed this as completed Sep 3, 2013
@osheroff osheroff reopened this Sep 3, 2013
@lukkry lukkry mentioned this issue Sep 3, 2013
@osheroff
Copy link
Contributor

osheroff commented Sep 3, 2013

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?

@staugaard
Copy link
Contributor

Something like what I did for the old ticket archive. RelationFromArchive in https://github.com/zendesk/zendesk/blob/master/lib/archive.rb

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants