2011-01-15 3 views
28

schema.rb 대신 schema.sql을 생성하려고합니다. 인터넷 검색 후 나는 application.rb에 SQL 스키마 형식을 설정하여이를 수행 할 수 있음을 발견했습니다. 그래서 application.rbschema_format = : sql을 설정 한 후에도 schema.sql이 생성되지 않음

config.active_record.schema_format = :sql 

에서 다음을 설정합니다하지만 난에 schema_format를 설정 한 경우 : SQL, schema.rb/schema.sql 전혀 만들어지지 않습니다. 위 줄에 주석을 달면 schema.rb가 생성되지만 schema.sql이 필요합니다. 나는 데이터베이스 구조가에 버려진있을 것이라는 점을 가정하고 있어요 나는 데이터베이스 구조가

rake db:structure:dump 

를 사용하여 덤프 할 수 있다는 사실을 알고하지만 데이터베이스 마이그레이션 할 때 자동으로 수행하고자합니다.

내가 누락되었거나 잘못 가정하는 것이 있습니까?

답변

33

원래 질문의 5 개월 후 문제가 여전히 존재합니다. 그 대답은 당신이 모든 것을 올바르게 했음에도 레일스에 버그가 있다는 것입니다. SQL하지만 마이그레이션 작업이 (액티브/lib 디렉토리/active_record/railties/databases.rake 라인 155)과 같이 정의된다 : 루비 : 당신이 필요로하는 모든이의 형식을 변경하는 것처럼

에도 the guides에 보이는

task :migrate => [:environment, :load_config] do 
    ActiveRecord::Migration.verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] == "true" : true 
    ActiveRecord::Migrator.migrate(ActiveRecord::Migrator.migrations_paths, ENV["VERSION"] ? ENV["VERSION"].to_i : nil) 
    db_namespace["schema:dump"].invoke if ActiveRecord::Base.schema_format == :ruby 
end 

볼 수 있듯이 schema_format이 : ruby와 같지 않으면 아무 일도 발생하지 않습니다. Rails 1.x에서 SQL 형식의 스키마 자동 덤핑이 작동했습니다. Rails 2에서 뭔가가 변경되어 수정되지 않았습니다.

SQL 형식으로 스키마를 생성해도 데이터베이스에로드 할 작업이 없으며 rake db:setup 작업은 데이터베이스 구조를 무시합니다. , https://github.com/rails/rails/issues/715 (및 issues/715)이, 그리고 당신은 패치 (가장자리 버전은 여전히이 버그가) 레일에 적용될 때까지 기다려야 할 수도 있습니다 https://gist.github.com/971720

에서 패치가 :

버그는 최근에 발견 된 패치를 직접 적용하십시오 (행 번호가 약간 변경되었으므로 수동으로해야 할 수도 있음).


해결 방법 : 라이브러리 를 (업그레이드가 자주 수행되고 경로가 이상한 번호로 오염되는 것을, 그래서 쉽게 패치하기가 상대적으로 어렵다 들러와

- 적어도 경우 대신 파일을 직접 패치의 가장자리 레일 ;-)을 사용하기 때문에, 당신은 당신의 lib/tasks 폴더에 두 개의 파일을 만들 수 있습니다 :

lib/tasks/schema_format.rake을 :

import File.expand_path(File.dirname(__FILE__)+"/schema_format.rb") 

# Loads the *_structure.sql file into current environment's database. 
# This is a slightly modified copy of the 'test:clone_structure' task. 
def db_load_structure(filename) 
    abcs = ActiveRecord::Base.configurations 
    case abcs[Rails.env]['adapter'] 
    when /mysql/ 
    ActiveRecord::Base.establish_connection(Rails.env) 
    ActiveRecord::Base.connection.execute('SET foreign_key_checks = 0') 
    IO.readlines(filename).join.split("\n\n").each do |table| 
     ActiveRecord::Base.connection.execute(table) 
    end 
    when /postgresql/ 
    ENV['PGHOST']  = abcs[Rails.env]['host'] if abcs[Rails.env]['host'] 
    ENV['PGPORT']  = abcs[Rails.env]['port'].to_s if abcs[Rails.env]['port'] 
    ENV['PGPASSWORD'] = abcs[Rails.env]['password'].to_s if abcs[Rails.env]['password'] 
    `psql -U "#{abcs[Rails.env]['username']}" -f #{filename} #{abcs[Rails.env]['database']} #{abcs[Rails.env]['template']}` 
    when /sqlite/ 
    dbfile = abcs[Rails.env]['database'] || abcs[Rails.env]['dbfile'] 
    `sqlite3 #{dbfile} < #{filename}` 
    when 'sqlserver' 
    `osql -E -S #{abcs[Rails.env]['host']} -d #{abcs[Rails.env]['database']} -i #{filename}` 
    # There was a relative path. Is that important? : db\\#{Rails.env}_structure.sql` 
    when 'oci', 'oracle' 
    ActiveRecord::Base.establish_connection(Rails.env) 
    IO.readlines(filename).join.split(";\n\n").each do |ddl| 
     ActiveRecord::Base.connection.execute(ddl) 
    end 
    when 'firebird' 
    set_firebird_env(abcs[Rails.env]) 
    db_string = firebird_db_string(abcs[Rails.env]) 
    sh "isql -i #{filename} #{db_string}" 
    else 
    raise "Task not supported by '#{abcs[Rails.env]['adapter']}'" 
    end 
end 

namespace :db do 
    namespace :structure do 
    desc "Load development_structure.sql file into the current environment's database" 
    task :load => :environment do 
     file_env = 'development' # From which environment you want the structure? 
           # You may use a parameter or define different tasks. 
     db_load_structure "#{Rails.root}/db/#{file_env}_structure.sql" 
    end 
    end 
end 

lib/tasks/schema_format.rb :이 파일을 갖는

def dump_structure_if_sql 
    Rake::Task['db:structure:dump'].invoke if ActiveRecord::Base.schema_format == :sql 
end 
Rake::Task['db:migrate'  ].enhance do dump_structure_if_sql end 
Rake::Task['db:migrate:up' ].enhance do dump_structure_if_sql end 
Rake::Task['db:migrate:down'].enhance do dump_structure_if_sql end 
Rake::Task['db:rollback' ].enhance do dump_structure_if_sql end 
Rake::Task['db:forward'  ].enhance do dump_structure_if_sql end 

Rake::Task['db:structure:dump'].enhance do 
    # If not reenabled, then in db:migrate:redo task the dump would be called only once, 
    # and would contain only the state after the down-migration. 
    Rake::Task['db:structure:dump'].reenable 
end 

# The 'db:setup' task needs to be rewritten. 
Rake::Task['db:setup'].clear.enhance(['environment']) do # see the .clear method invoked? 
    Rake::Task['db:create'].invoke 
    Rake::Task['db:schema:load'].invoke if ActiveRecord::Base.schema_format == :ruby 
    Rake::Task['db:structure:load'].invoke if ActiveRecord::Base.schema_format == :sql 
    Rake::Task['db:seed'].invoke 
end 

, 당신은 레이크 작업을 monkeypatched 있고, 당신은 여전히 ​​쉽게 레일을 업그레이드 할 수 있습니다. 물론, activerecord/lib/active_record/railties/databases.rake 파일에 소개 된 변경 사항을 모니터링하고 수정이 필요한지 여부를 결정해야합니다.

+1

나는 좋은 해결책이 될 수 있다면 +10을 주겠다. 내 경우도 해결했다. – KensoDev

+4

좋은 소식은 이것이 해결되었다는 것입니다. 나쁜 소식은 3.2.0 릴리스 후보자가 3.1.x로 포팅되지 않았다는 신호가 없다는 것입니다. 3.2.0 결승전이 언제 중단 될지 누가 알겠는가? 커밋 참조 : https://github.com/rails/rails/commit/15fb4302b6ff16e641b6279a3530eb8ed97f2899 –

+0

다시 한 번 좋은 소식은 3.2.0입니다. –

-3

schema.sql을 만들려면 schema.rb을 삭제해야 할 수 있습니다.

+1

나는 필요하지 않았습니다. –

13

나는 레일 2.3.5를 사용하고 있지만, 이것은뿐만 아니라 3.0에 적용 할 수 있습니다

레이크 DB : 구조 : 나를 위해 트릭을 수행 덤프.

+0

이것은 (적어도 내가 사용하고있는 3.2.7에서는) 작동하지 않습니다. 'Rails '테이블을 가지고 있지 않은 레거시 데이터베이스의 스키마를 덤프하려고하기 때문에'table'schema_migrations 'does not exist'라는 메시지와 함께 실패합니다. – Andrew

+1

수정 사항 : structure.sql 파일이 올바르게 작성된 것 같습니다. 왜 내가이 오류가 점점 확실하지. – Andrew

관련 문제