【问题标题】:Rails migration: establish_connection creates table in wrong databaseRails 迁移:建立连接在错误的数据库中创建表
【发布时间】:2012-08-18 19:43:17
【问题描述】:

我想在我的 database.yml 文件中定义的数据库之外的数据库中创建一个新表。

这是我的 database.yml 文件:

development:                                                                                                                                                                    
  adapter: mysql2                                                                                                                                                               
  encoding: utf8                                                                                                                                                                
  reconnect: false                                                                                                                                                              
  database: main_development                                                                                                                                                    
  pool: 5                                                                                                                                                                       
  username: root                                                                                                                                                                
  password:                                                                                                                                                                     
  socket: /var/run/mysqld/mysqld.sock                                                                                                                                           

test:                                                                                                                                                                           
  adapter: mysql2                                                                                                                                                               
  encoding: utf8                                                                                                                                                                
  reconnect: false                                                                                                                                                              
  database: main_test                                                                                                                                                    
  pool: 5                                                                                                                                                                       
  username: root                                                                                                                                                                
  password:                                                                                                                                                                     
  socket: /var/run/mysqld/mysqld.sock  

production:                                                                                                                                                                           
  adapter: mysql2                                                                                                                                                               
  encoding: utf8                                                                                                                                                                
  reconnect: false                                                                                                                                                              
  database: main_prod                                                                                                                                                    
  pool: 5                                                                                                                                                                       
  username: root                                                                                                                                                                
  password:                                                                                                                                                                     
  socket: /var/run/mysqld/mysqld.sock  

我有另一个名为“peripheral”的数据库。我想在该数据库中创建一个名为“retailer_to_domain”的表。

这是我的迁移文件:

class CreateRetailerToDomains < ActiveRecord::Migration                                                                                                                         

      def connection                                                                                                                                                                
        ActiveRecord::Base.establish_connection(                                                                                                                                    
        :adapter => "mysql2",                                                                                                                                                       
        :encoding => "utf8",                                                                                                                                                        
        :reconnect => false,                                                                                                                                                        
        :database => "peripheral",                                                                                                                                                 
        :pool => 5,                                                                                                                                                                 
        :username => "root",                                                                                                                                                        
        :password => "",                                                                                                                                                            
        :socket => "/var/run/mysqld/mysqld.sock").connection                                                                                                                        
      end                                                                                                                                                                           

      def change                                                                                                                                                                    
        ActiveRecord::Base.connection.create_table :retailer_to_domains do |t|                                                                                            
          t.string :name                                                                                                                                                            
          t.string :domain                                                                                                                                                          

          t.timestamps                                                                                                                                                              
        end                                                                                                                                                                         
      end                                                                                                                                                                           
    end           

迁移文件由以下命令生成:rails generate model RetailerToDomain name:string domain:string,然后我添加了def connection 方法来覆盖 database.yml 配置中的默认数据库(“main”)。

当我运行迁移 (rake db:migrate) 时,retailer_to_domains 表在 main_development 数据库中创建。如何覆盖此默认值以使迁移在我想要的位置创建表?

另外,我希望 RetailerToDomain 模型以类似的方式访问此表,建立连接方法如下所示:

class RetailerToDomain < ActiveRecord::Base                                                                                                                                     

 establish_connection(                                                                                                                                    
            :adapter => "mysql2",                                                                                                                                                       
            :encoding => "utf8",                                                                                                                                                        
            :reconnect => false,                                                                                                                                                        
            :database => "peripheral",                                                                                                                                                 
            :pool => 5,                                                                                                                                                                 
            :username => "root",                                                                                                                                                        
            :password => "",                                                                                                                                                            
            :socket => "/var/run/mysqld/mysqld.sock")

self.table=retailer_to_domain

validates_presence_of :name, :domain

end  

提前感谢这里的任何想法!

【问题讨论】:

    标签: ruby-on-rails-3 migration


    【解决方案1】:

    观看此页面!

    https://github.com/rails/rails/issues/3497

    创建 rake 文件

    # Augment the main migration to migrate your engine, too.
    task 'db:migrate', 'your_engine:db:migrate'
    
    # Augment to dump/load the engine schema, too
    task 'db:schema:dump', 'your_engine:db:schema:dump'
    task 'db:schema:load', 'your_engine:db:schema:load'
    
    namespace :your_engine do
      namespace :db do
        desc 'Migrates the your_engine database'
        task :migrate => :environment do
          p "your_engine db migrate"
          with_engine_connection do
            ActiveRecord::Migrator.migrate("#{File.dirname(__FILE__)}/../../db/migrate/your_engine", ENV['VERSION'].try(:to_i))
          end
          Rake::Task['your_engine:db:schema:dump'].invoke
        end
    
        task :'schema:dump' => :environment do
          require 'active_record/schema_dumper'
    
          with_engine_connection do
            File.open(File.expand_path('../../../db/your_engine_schema.rb', __FILE__), 'w') do |file|
              ActiveRecord::SchemaDumper.dump ActiveRecord::Base.connection, file
            end
          end
        end
    
        task :'schema:load' => :environment do
          with_engine_connection do
            load File.expand_path('../../../db/your_engine_schema.rb', __FILE__)
          end
        end
      end
    end
    
    # Hack to temporarily connect AR::Base to your_engine.
    def with_engine_connection
      original = ActiveRecord::Base.remove_connection
      ActiveRecord::Base.establish_connection "your_engine_#{Rails.env}".to_sym
      yield
    ensure
      ActiveRecord::Base.establish_connection original
    end
    

    型号

    class YourModel < ActiveRecord::Base
        establish_connection "your_engine_#{Rails.env}".tom_sym
    end
    

    数据库.yaml

    your_engine_development:
      adapter: 
      database:
      encoding:
      username:
      password:
      host:
    

    【讨论】:

      【解决方案2】:
              Add another database connection seeting to database.yml file.
      
              database.yml file
      
                  development:                                                                                                                                                                    
                    adapter: mysql2                                                                                                                                                               
                    encoding: utf8                                                                                                                                                                
                    reconnect: false                                                                                                                                                              
                    database: main_development                                                                                                                                                    
                    pool: 5                                                                                                                                                                       
                    username: root                                                                                                                                                                
                    password:                                                                                                                                                                     
                    socket: /var/run/mysqld/mysqld.sock                                                                                                                                           
      
                  test:                                                                                                                                                                           
                    adapter: mysql2                                                                                                                                                               
                    encoding: utf8                                                                                                                                                                
                    reconnect: false                                                                                                                                                              
                    database: main_test                                                                                                                                                    
                    pool: 5                                                                                                                                                                       
                    username: root                                                                                                                                                                
                    password:                                                                                                                                                                     
                    socket: /var/run/mysqld/mysqld.sock  
      
                  production:                                                                                                                                                                           
                    adapter: mysql2                                                                                                                                                               
                    encoding: utf8                                                                                                                                                                
                    reconnect: false                                                                                                                                                              
                    database: main_prod                                                                                                                                                    
                    pool: 5                                                                                                                                                                       
                    username: root                                                                                                                                                                
                    password:                                                                                                                                                                     
                    socket: /var/run/mysqld/mysqld.sock 
      
          another_database:
                      adapter: "mysql2",                                                                                                                                                       
                      encoding: "utf8",                                                                                                                                                        
                      reconnect: false,                                                                                                                                                        
                      database: "peripheral",                                                                                                                                                 
                      pool: 5,                                                                                                                                                                 
                      username: "root",                                                                                                                                                        
                      password: "",                                                                                                                                                            
                      socket: "/var/run/mysqld/mysqld.sock"
      
      
      
      Now In Migration file specify:
      ActiveRecord::Base.establish_connection(:another_database)
      
      
      class CreateRetailerToDomains < ActiveRecord::Migration
      ActiveRecord::Base.establish_connection(:another_database)
       def change                                                                                                                                                                    
           create_table :retailer_to_domains do |t|                                                                                            
                t.string :name                                                                                                                                                            
                t.string :domain                                                                                                                                                          
      
                t.timestamps                                                                                                                                                              
              end                                                                                                                                                                         
            end                                                                                                                                                                           
          end  
      
      
      
       It will get create table inside that database only.
      
      
      Model
      
      class RetailerToDomain < ActiveRecord::Base
        ActiveRecord::Base.establish_connection(:another_database)
      end
      
      
      **To check the active database connection**
      ActiveRecord::Base.connection.current_database
      

      【讨论】:

        【解决方案3】:

        在你的config/database.yml:

        new_connect_development:
          adapter: mysql2
          encoding: utf8
          reconnect: false
          database: new_database_development
          pool: 5
          username: root
          password:
          socket: /tmp/mysql.sock
        

        所有其他环境都使用相同的块。然后添加到您的迁移(rails 2.x-3.0 的示例,rails 3.1 的删除 self):

          def self.connection
            ActiveRecord::Base.establish_connection("new_connect_#{RAILS_ENV}").connection
          end
        

        并在模型中添加以下行,与新数据库中的表相对应:

        class ModelName < ActiveRecord::Base
          establish_connection "new_connect_#{RAILS_ENV}"
        end
        

        【讨论】:

        • 至少在 Rails >= 4.0 中你应该使用 Rails.env 而不是 RAILS_ENV。这让我很烦。
        • 我正在使用 Rails 4,我无法进行迁移,出现类似 SQLite3::SQLException: table "table_name" 已经存在的错误。我已经在 database.yml 中设置了 mysql2 和 sqlite 连接。错误是什么意思?请帮忙!
        • 哦,我发现了我的错误,我使用的是 Rails 4,所以需要 def self.connection。我忘记了 self 方法:)
        猜你喜欢
        • 2015-05-17
        • 2013-04-20
        • 1970-01-01
        • 2021-12-14
        • 1970-01-01
        • 2015-12-21
        • 1970-01-01
        • 2018-12-03
        • 1970-01-01
        相关资源
        最近更新 更多