Cinque mesi dopo la domanda originale il problema esiste ancora. La risposta è che hai fatto tutto correttamente, ma c'è un bug in Rails.
Anche in the guides sembra che tutto ciò che serve è quello di cambiare il formato da: ruby a: sql, ma il compito migrazione è definito come questo (ActiveRecord/lib/active_record/railties/databases.rake linea 155):
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
Come si può vedere, non succede nulla a meno che lo schema_formato sia uguale: rubino. Il dumping automatico dello schema in formato SQL funzionava in Rails 1.x. Qualcosa è cambiato in Rails 2 e non è stato corretto.
Il problema è che anche se si riesce a creare lo schema in formato SQL, non è possibile caricarlo nel database e l'attività rake db:setup
ignorerà la struttura del database.
Il bug è stato notato di recente: https://github.com/rails/rails/issues/715 (e issues/715), e c'è una patch al https://gist.github.com/971720
Si consiglia di attendere che il cerotto deve essere applicato Rails (la versione bordo ha ancora questo bug), oppure applicare la patch da soli (potrebbe essere necessario farlo manualmente, poiché i numeri di riga sono leggermente cambiati).
Soluzione:
Con bundler è relativamente difficile da rattoppare le librerie (gli aggiornamenti sono così facili, che sono fatte molto spesso ei percorsi sono inquinate con i numeri strani - almeno se si utilizzare bordo rotaie ;-), così, invece di patch direttamente il file, si consiglia di creare due file nella cartella 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
e 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
Avendo questi file, si hanno compiti monkeypatched rastrello, e ancora può facilmente aggiornare Rails. Naturalmente, è necessario monitorare le modifiche introdotte nel file activerecord/lib/active_record/railties/databases.rake
e decidere se le modifiche sono ancora necessarie.
Ti darei +10 se potessi, buona soluzione, risolto anche il mio caso. – KensoDev
La buona notizia è che questo è stato affrontato. La cattiva notizia è che è nella versione 3.2.0 candidati senza alcun segno di essere riportato su 3.1.x. Chissà quando scenderà la 3.2.0 finale. Vedi commettere: https://github.com/rails/rails/commit/15fb4302b6ff16e641b6279a3530eb8ed97f2899 –
Buone notizie ancora una volta, 3.2.0 è fuori! –