Hi, My application spans 2 (or more) databases for some very specific reasons... My models are working fine, even dynamically establishing connections as needed at runtime, and spanning relationships across the databases (which really impressed me). The problem is, I can''t seem to force Units for these models (that use a secondary db) to load their fixtures into and use the secondary database. I tried applying this: Project.establish_connection(:test_group) (where :test_group is a database connection defined in database.yml) at various locations within the test itself, and test_helper.rb... but my unit is failing with this error: ActiveRecord::StatementInvalid: Mysql::Error: Table ''scoot_test.projects'' doesn''t exist: DELETE FROM projects (and scoot_test is the ''main'' database, but projects should be a table in the ''secondary'' database) So, any advice on how I might be able to get this to work? Thanks, Mike
Hi Mikes, Rails stores the database tablename within the corresponding ActiveRecord::base subclass. inside the "connection_specification" class there is a hash which contains information about which class is using which db connection. and if there is no connection define for a class it will go to its parent. So what I understand, is that your have two databases, and the class can finf its table? am I right. if it is the case, it is because the class is using the wrong connection, so the worng database. SO I suggestion you to create two parents for your databases. like db1 <activeRecords::base and db2 <activeRecords::base. all the table-class from db1 should inherited not directly form activeRecords::base, but db1 and same for the table-class from db2. when you connect dynamically to your database, uses db1.establish_connection(...) so all the table-class used db1 will have the same db connection and the same for db2. actually, I''m using 2 db also. it works for me, so I hope it will work for you. Saiho --- Mike Evans <mike@urlgonomics.com> wrote:> Hi, > > My application spans 2 (or more) databases for some > very specific > reasons... My models are working fine, even > dynamically establishing > connections as needed at runtime, and spanning > relationships across the > databases (which really impressed me). The problem > is, I can''t seem to > force Units for these models (that use a secondary > db) to load their > fixtures into and use the secondary database. > > I tried applying this: > > Project.establish_connection(:test_group) > (where :test_group is a database connection defined > in database.yml) > > at various locations within the test itself, and > test_helper.rb... but > my unit is failing with this error: > > ActiveRecord::StatementInvalid: Mysql::Error: Table > ''scoot_test.projects'' doesn''t exist: DELETE FROM > projects > (and scoot_test is the ''main'' database, but projects > should be a table > in the ''secondary'' database) > > So, any advice on how I might be able to get this to > work? > > Thanks, > Mike > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails >__________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com
Thanks Saiho, If I understand you correctly, that''s kind of what I''m doing... Project < ActiveRecord::Base Project.establish_connection(:db2) end And all other models in db2 inherit from Project. That works fine from the console... the problem is, when trying to write unit tests, the fixtures for Project are being loaded into (well, attempted at least) db1, but I can''t figure out why that would be. I tried this: Project < ActiveRecord::Base Project.establish_connection(:db2) if (RAILS_ENV == "test") then Project.establish_connection(:db2_test) end end But it''s still trying to load things into db1_test... it almost seems like ActiveRecord::Base.establish_connection is turned off during testing... M. Saiho Yuen wrote:> Hi Mikes, > > Rails stores the database tablename within the > corresponding ActiveRecord::base subclass. inside the > "connection_specification" class there is a hash which > contains information about which class is using which > db connection. and if there is no connection define > for a class it will go to its parent. > > So what I understand, is that your have two databases, > and the class can finf its table? am I right. > > if it is the case, it is because the class is using > the wrong connection, so the worng database. > > SO I suggestion you to create two parents for your > databases. like db1 <activeRecords::base and db2 > <activeRecords::base. all the table-class from db1 > should inherited not directly form > activeRecords::base, but db1 and same for the > table-class from db2. when you connect dynamically to > your database, uses > > db1.establish_connection(...) so all the table-class > used db1 will have the same db connection and the same > for db2. > > actually, I''m using 2 db also. it works for me, so I > hope it will work for you. > > Saiho > >
Hi Mike, Did you try to connect to 2 db within the same action? if it is the case, I have an example code, that may help, but not for all db, I''m using postgresql. so not sure that it will work for all other databse. if you are trying to use two different database in two different action/controllers, there is an example on http://wiki.rubyonrails.org/rails/pages/HowtoUseMultipleDatabases May be you should try: Project < ActiveRecord::Base if (RAILS_ENV == "test") then Project.establish_connection(:db2_test) Project.establish_connection(:db2)> end > end--- Mike Evans <mike@urlgonomics.com> wrote:> Thanks Saiho, > > If I understand you correctly, that''s kind of what > I''m doing... > Project < ActiveRecord::Base > Project.establish_connection(:db2) > end > And all other models in db2 inherit from Project. > > That works fine from the console... the problem is, > when trying to write > unit tests, the fixtures for Project are being > loaded into (well, > attempted at least) db1, but I can''t figure out why > that would be. > > I tried this: > Project < ActiveRecord::Base > Project.establish_connection(:db2) > if (RAILS_ENV == "test") then > Project.establish_connection(:db2_test) > end > end > > But it''s still trying to load things into > db1_test... it almost seems > like ActiveRecord::Base.establish_connection is > turned off during > testing... > > M. > > Saiho Yuen wrote: > > Hi Mikes, > > > > Rails stores the database tablename within the > > corresponding ActiveRecord::base subclass. inside > the > > "connection_specification" class there is a hash > which > > contains information about which class is using > which > > db connection. and if there is no connection > define > > for a class it will go to its parent. > > > > So what I understand, is that your have two > databases, > > and the class can finf its table? am I right. > > > > if it is the case, it is because the class is > using > > the wrong connection, so the worng database. > > > > SO I suggestion you to create two parents for your > > databases. like db1 <activeRecords::base and db2 > > <activeRecords::base. all the table-class from db1 > > should inherited not directly form > > activeRecords::base, but db1 and same for the > > table-class from db2. when you connect > dynamically to > > your database, uses > > > > db1.establish_connection(...) so all the > table-class > > used db1 will have the same db connection and the > same > > for db2. > > > > actually, I''m using 2 db also. it works for me, so > I > > hope it will work for you. > > > > Saiho > > > > > > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails >If God really exists, I would like to know what the dinosaurs have done to deserve their extinction. Water is unknown to fishes, until they discover air. http://www.geocities.com/sayoyo/ __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com
I took a look at this a few months ago. It looks like the test code is just broken for multiple databases. The only database the code uses is the one set for Base, so your per-model database won''t work during testing. It looked to be a non-trivial piece of work to make the test code work with multiple databases, so I moved on to something else. In my case, it doesn''t matter too much, as I only have one very simple model in my second DB, and it''s real obvious in my app when it breaks! -----Original Message----- From: rails-bounces@lists.rubyonrails.org [mailto:rails-bounces@lists.rubyonrails.org] On Behalf Of Saiho Yuen Sent: Wednesday, February 08, 2006 10:59 AM To: rails@lists.rubyonrails.org Subject: Re: [Rails] Strategies for Unit testing 2 databases Hi Mike, Did you try to connect to 2 db within the same action? if it is the case, I have an example code, that may help, but not for all db, I''m using postgresql. so not sure that it will work for all other databse. if you are trying to use two different database in two different action/controllers, there is an example on http://wiki.rubyonrails.org/rails/pages/HowtoUseMultipleDatabases May be you should try: Project < ActiveRecord::Base if (RAILS_ENV == "test") then Project.establish_connection(:db2_test) Project.establish_connection(:db2)> end > end--- Mike Evans <mike@urlgonomics.com> wrote:> Thanks Saiho, > > If I understand you correctly, that''s kind of what > I''m doing... > Project < ActiveRecord::Base > Project.establish_connection(:db2) > end > And all other models in db2 inherit from Project. > > That works fine from the console... the problem is, > when trying to write > unit tests, the fixtures for Project are being > loaded into (well, > attempted at least) db1, but I can''t figure out why > that would be. > > I tried this: > Project < ActiveRecord::Base > Project.establish_connection(:db2) > if (RAILS_ENV == "test") then > Project.establish_connection(:db2_test) > end > end > > But it''s still trying to load things into > db1_test... it almost seems > like ActiveRecord::Base.establish_connection is > turned off during > testing... > > M. > > Saiho Yuen wrote: > > Hi Mikes, > > > > Rails stores the database tablename within the > > corresponding ActiveRecord::base subclass. inside > the > > "connection_specification" class there is a hash > which > > contains information about which class is using > which > > db connection. and if there is no connection > define > > for a class it will go to its parent. > > > > So what I understand, is that your have two > databases, > > and the class can finf its table? am I right. > > > > if it is the case, it is because the class is > using > > the wrong connection, so the worng database. > > > > SO I suggestion you to create two parents for your > > databases. like db1 <activeRecords::base and db2 > > <activeRecords::base. all the table-class from db1 > > should inherited not directly form > > activeRecords::base, but db1 and same for the > > table-class from db2. when you connect > dynamically to > > your database, uses > > > > db1.establish_connection(...) so all the > table-class > > used db1 will have the same db connection and the > same > > for db2. > > > > actually, I''m using 2 db also. it works for me, so > I > > hope it will work for you. > > > > Saiho > > > > > > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails >If God really exists, I would like to know what the dinosaurs have done to deserve their extinction. Water is unknown to fishes, until they discover air. http://www.geocities.com/sayoyo/ __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com _______________________________________________ Rails mailing list Rails@lists.rubyonrails.org http://lists.rubyonrails.org/mailman/listinfo/rails
sorry, I pressed on the wrong button:) what I want ot say is: May be you should try: Project < ActiveRecord::Base if (RAILS_ENV == "test") then Project.establish_connection(:db2_test) else Project.establish_connection(:db2) end I think this is better, because the class will not be assigned two times. --- Saiho Yuen <sayoyo@yahoo.com> wrote:> Hi Mike, > > Did you try to connect to 2 db within the same > action? > if it is the case, I have an example code, that may > help, but not for all db, I''m using postgresql. so > not > sure that it will work for all other databse. > > if you are trying to use two different database in > two > different action/controllers, there is an example on >http://wiki.rubyonrails.org/rails/pages/HowtoUseMultipleDatabases> > May be you should try: > Project < ActiveRecord::Base > if (RAILS_ENV == "test") then > Project.establish_connection(:db2_test) > > Project.establish_connection(:db2) > > > > end > > end > > > > > > --- Mike Evans <mike@urlgonomics.com> wrote: > > > Thanks Saiho, > > > > If I understand you correctly, that''s kind of what > > I''m doing... > > Project < ActiveRecord::Base > > Project.establish_connection(:db2) > > end > > And all other models in db2 inherit from Project. > > > > That works fine from the console... the problem > is, > > when trying to write > > unit tests, the fixtures for Project are being > > loaded into (well, > > attempted at least) db1, but I can''t figure out > why > > that would be. > > > > I tried this: > > Project < ActiveRecord::Base > > Project.establish_connection(:db2) > > if (RAILS_ENV == "test") then > > Project.establish_connection(:db2_test) > > end > > end > > > > But it''s still trying to load things into > > db1_test... it almost seems > > like ActiveRecord::Base.establish_connection is > > turned off during > > testing... > > > > M. > > > > Saiho Yuen wrote: > > > Hi Mikes, > > > > > > Rails stores the database tablename within the > > > corresponding ActiveRecord::base subclass. > inside > > the > > > "connection_specification" class there is a hash > > which > > > contains information about which class is using > > which > > > db connection. and if there is no connection > > define > > > for a class it will go to its parent. > > > > > > So what I understand, is that your have two > > databases, > > > and the class can finf its table? am I right. > > > > > > if it is the case, it is because the class is > > using > > > the wrong connection, so the worng database. > > > > > > SO I suggestion you to create two parents for > your > > > databases. like db1 <activeRecords::base and db2 > > > <activeRecords::base. all the table-class from > db1 > > > should inherited not directly form > > > activeRecords::base, but db1 and same for the > > > table-class from db2. when you connect > > dynamically to > > > your database, uses > > > > > > db1.establish_connection(...) so all the > > table-class > > > used db1 will have the same db connection and > the > > same > > > for db2. > > > > > > actually, I''m using 2 db also. it works for me, > so > > I > > > hope it will work for you. > > > > > > Saiho > > > > > > > > > > _______________________________________________ > > Rails mailing list > > Rails@lists.rubyonrails.org > > > http://lists.rubyonrails.org/mailman/listinfo/rails > > > > > If God really exists, I would like to > know what the dinosaurs have done to > deserve their extinction. > > Water is unknown to fishes, > until they discover air. > > http://www.geocities.com/sayoyo/ > > __________________________________________________ > Do You Yahoo!? > Tired of spam? Yahoo! Mail has the best spam > protection around > http://mail.yahoo.com > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails >__________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com
Tom Fakes wrote:> I took a look at this a few months ago. > > It looks like the test code is just broken for multiple databases. The only > database the code uses is the one set for Base, so your per-model database > won''t work during testing. > > It looked to be a non-trivial piece of work to make the test code work with > multiple databases, so I moved on to something else. > > In my case, it doesn''t matter too much, as I only have one very simple model > in my second DB, and it''s real obvious in my app when it breaks! > > -----Original Message----- > From: rails-bounces@lists.rubyonrails.org > [mailto:rails-bounces@lists.rubyonrails.org] On Behalf Of Saiho Yuen > Sent: Wednesday, February 08, 2006 10:59 AM > To: rails@lists.rubyonrails.org > Subject: Re: [Rails] Strategies for Unit testing 2 databases > > Hi Mike, > > Did you try to connect to 2 db within the same action? > if it is the case, I have an example code, that may > help, but not for all db, I''m using postgresql. so not > sure that it will work for all other databse. > > if you are trying to use two different database in two > different action/controllers, there is an example on > http://wiki.rubyonrails.org/rails/pages/HowtoUseMultipleDatabases > > May be you should try: > Project < ActiveRecord::Base > if (RAILS_ENV == "test") then > Project.establish_connection(:db2_test) > > Project.establish_connection(:db2) > > >Ok, I''ve been digging into ActiveRecord and fixtures.rb and it looks like the reason this is broken is because fixtures don''t really look at models to do their magic... they (by default) use the db connection of ActiveRecord::Base. I found a couple ways around this... The more complicated way (which doesn''t seem to work anyway) was to create your own instance of Fixtures: class ProjectTest < Test::Unit::TestCase fixtures :groups Project.establish_connection(:test_group) @fix = Fixtures.new(Project.connection, "projects", File.dirname(__FILE__) + "/../fixtures") @fix.insert_fixtures .... The problem is insert_fixtures isn''t really doing anything... I''m sure there''s a way I just don''t completely understand the API. I moved onto another method, which is to create my own custom rake tasks that will load my custom fixtures into the 2nd database as needed. Then I''ll insert it into the default test_units and test_functional tasks. I''ll post the results as soon as I''m done. m
Agnieszka Figiel
2006-Feb-22 11:49 UTC
[Rails] Re: Strategies for Unit testing 2 databases
Mike Evans wrote:> Ok, I''ve been digging into ActiveRecord and fixtures.rb and it looks > like the reason this is broken is because fixtures don''t really look at > models to do their magic... they (by default) use the db connection of > ActiveRecord::Base. > > I found a couple ways around this... The more complicated way (which > doesn''t seem to work anyway) was to create your own instance of > Fixtures: > class ProjectTest < Test::Unit::TestCase > fixtures :groups > Project.establish_connection(:test_group) > @fix = Fixtures.new(Project.connection, "projects", > File.dirname(__FILE__) + "/../fixtures") > @fix.insert_fixtures > .... > > The problem is insert_fixtures isn''t really doing anything... I''m sure > there''s a way I just don''t completely understand the API. > > I moved onto another method, which is to create my own custom rake tasks > that will load my custom fixtures into the 2nd database as needed. Then > I''ll insert it into the default test_units and test_functional tasks. > I''ll post the results as soon as I''m done. > > mHello, this seems to be working: in the model: if ENV["RAILS_ENV"]=="test" Person.establish_connection "db_test" else Person.establish_connection "db" end in the test - instead of "fixtures :people" something like this: Fixtures.create_fixtures(File.dirname(__FILE__) + "/../fixtures", ["people"]){Person.connection} the connection can be passed in a block. I''d love to see this or better solution in the chapter on using multiple databases in Rails Recipes. Please :) -- Agnieszka Figiel -- Posted via http://www.ruby-forum.com/.
> Hello, > > this seems to be working: > > in the model: > > if ENV["RAILS_ENV"]=="test" > Person.establish_connection "db_test" > else > Person.establish_connection "db" > end > > in the test - instead of "fixtures :people" something like this: > > Fixtures.create_fixtures(File.dirname(__FILE__) + "/../fixtures", > ["people"]){Person.connection} > > the connection can be passed in a block. I''d love to see this or better > solution in the chapter on using multiple databases in Rails Recipes. > Please :) >Great idea! I''m adding this (or something like it) to my TODO list. Thanks! -- Chad Fowler http://chadfowler.com http://pragmaticprogrammer.com/titles/fr_rr/ (Rails Recipes - In Beta!) http://pragmaticprogrammer.com/titles/mjwti/ (My Job Went to India, and All I Got Was This Lousy Book) http://rubycentral.org http://rubygarden.org http://rubygems.rubyforge.org (over one million gems served!)