Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

schema_migrations already exists error on db:migrate with two-database app

#4961

Although we have a unique situation with a single app connecting to two databases which also needs to perform joins across the two (mysql only), when setting this up we break migrations such that we see the following error:

Mysql::Error: Table 'schema_migrations' already exists: CREATE TABLE istads_dev.schema_migrations (version varchar(255) NOT NULL) ENGINE=InnoDB

This problem was first discovered on 2.3.5 and still exists on 2.3.8. From what I can tell from code inspection, the problem is fixed on 3.0.

I found the problematic line in:
lib/active_record/connection_adapters/abstract/schema_statements.rb in the initialize_schema_migrations_table method, which first tries to detect if schema_migrations exists or not. This check fails because it is comparing the items returned from the tables method (strings of table names, not prefixed/suffixed) with the return value from ActiveRecord::Migrator.schema_migrations_table_name (which, in our case, includes the database prefix). The check always fails, even when schema_migrations exists, thus the code to recreate it is where the exception occurs.

I've created a one-line patch which I have attached to this ticket.

I have run the following rake tests with all tests passing:
test_mysql test_sqlite3 test_postgresql

Reported by Wade Stebbings · June 24th, 2010 @ 10:03 PM

State: open
Milestone: 2.3.10
Assigned to: nobody
Importance: Low

Activity

  1. Wade Stebbings
    Wade Stebbings

    I have not yet created a unique unit-test for this issue, but I've started looking into it.

    To recreate the problem, a part of the description which skimmed-over in the description above, I have these things going on in my rails app:

    • The app connects to two databases, one as the natural rails database, and one read-only metadata database which is quite huge. Models for the metadata database inherit from an abstract class called Metadata:

    class Metadata < ActiveRecord::Base

    self.abstract_class = true

    def self.database_name

    metadata = "#{RAILS_ENV}_metadata"
    configurations[metadata]['database']
    

    end

    def self.connect_to_metadata_database

    metadata = "#{RAILS_ENV}_metadata"
    @schema_prefix = Metadata.database_name + '.'
    self.establish_connection metadata
        puts "Connected to #{metadata.inspect}"
    

    end

    connect_to_metadata_database

    def self.table_name_prefix

    @schema_prefix
    

    end

    end

    • Also, in order to deal with another problem with allowing joins to occur across the two databases, I created an initializer file, which looks like this:

    class ActiveRecord::Base
    def self.set_schema_prefix

    @@schema_prefix = configurations[RAILS_ENV]['database'] + '.'
    

    end set_schema_prefix def self.table_name_prefix

    @@schema_prefix
    

    end end

    class ActiveRecord::ConnectionAdapters::MysqlAdapter
    def prefix_tables

    self.tables.map{|t| @@schema_prefix + t}
    

    end def self.set_schema_prefix

    @@schema_prefix = ActiveRecord::Base.configurations[RAILS_ENV]['database'] + '.'
    

    end set_schema_prefix end

    June 24th, 2010 @ 10:10 PM

  2. Wade Stebbings
    Wade Stebbings

    code-formatting got messed up above, here's another try..

    class Metadata < ActiveRecord::Base
      self.abstract_class = true
      def self.database_name
        metadata = "#{RAILS_ENV}_metadata"
        configurations[metadata]['database']
      end
      def self.connect_to_metadata_database
        metadata = "#{RAILS_ENV}_metadata"
        @schema_prefix = Metadata.database_name + '.'
        self.establish_connection metadata
            puts "Connected to #{metadata.inspect}"
      end
      connect_to_metadata_database
      def self.table_name_prefix
        @schema_prefix
      end
    end
    
    class ActiveRecord::Base
      def self.set_schema_prefix
        @@schema_prefix = configurations[RAILS_ENV]['database'] + '.'
      end
      set_schema_prefix
      def self.table_name_prefix
        @@schema_prefix
      end
    end
    
    class ActiveRecord::ConnectionAdapters::MysqlAdapter
      def prefix_tables
        self.tables.map{|t| @@schema_prefix + t}
      end
      def self.set_schema_prefix
        @@schema_prefix = ActiveRecord::Base.configurations[RAILS_ENV]['database'] + '.'
      end
      set_schema_prefix
    end
    

    June 24th, 2010 @ 10:13 PM

  3. Santiago Pastorino
    Santiago Pastorino
    • State changed from new to open

    This issue has been automatically marked as stale because it has not been commented on for at least three months.

    The resources of the Rails core team are limited, and so we are asking for your help. If you can still reproduce this error on the 3-0-stable branch or on master, please reply with all of the information you have about it and add "[state:open]" to your comment. This will reopen the ticket for review. Likewise, if you feel that this is a very important feature for Rails to include, please reply with your explanation so we can consider it.

    Thank you for all your contributions, and we hope you will understand this step to focus our efforts where they are most helpful.

    February 2nd, 2011 @ 05:01 PM

  4. Santiago Pastorino
    Santiago Pastorino
    • State changed from open to stale

    February 2nd, 2011 @ 05:01 PM

  5. Wade Stebbings
    Wade Stebbings

    I don't believe this problem exists in rails 3.0 from looking at the code itself, as stated in my original posting. This is a rails 2 issue only. If no work on rails 2 is going to occur, even the latest of the 2.x branches, then this issue can be closed.

    February 2nd, 2011 @ 07:11 PM

  6. Santiago Pastorino
    Santiago Pastorino
    • State changed from stale to open
    • Milestone set to 2.3.10
    • Importance changed from to Low

    February 2nd, 2011 @ 08:34 PM