Pra*_*vin 28 schema ruby-on-rails ruby-on-rails-3
我想创建schema.sql而不是schema.rb.谷歌搜索后我发现可以通过设置sql架构格式来完成application.rb
.所以我在application.rb中设置了以下内容
config.active_record.schema_format = :sql
Run Code Online (Sandbox Code Playgroud)
但是如果我将schema_format设置为:sql,则根本不会创建schema.rb/schema.sql.如果我在上面注释它创建schema.rb,但我需要schema.sql.我假设它将在其中转储数据库结构,我知道可以使用转储数据库结构
rake db:structure:dump
Run Code Online (Sandbox Code Playgroud)
但是我想在迁移数据库时自动完成它.
我有什么遗漏或假设错了吗?
Ars*_*en7 33
原问题提出五个月后问题仍然存在.答案是你做的一切都正确,但Rails中有一个错误.
即使在指南中,您看起来所需要的只是将格式从:ruby更改为:sql,但是迁移任务定义如下(activerecord/lib/active_record/railties/databases.rake第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
Run Code Online (Sandbox Code Playgroud)
如您所见,除非schema_format等于:ruby,否则不会发生任何事情.在Rails 1.x中,以SQL格式自动转储模式.Rails 2中的某些内容已经发生了变化,并且尚未修复.
问题是即使您设法以SQL格式创建模式,也没有任务将其加载到数据库中,任务rake db:setup
将忽略您的数据库结构.
最近发现了这个bug:https://github.com/rails/rails/issues/715(和issues/715),还有一个补丁:https://gist.github.com/971720
您可能希望等到修补程序应用于Rails(边缘版本仍然存在此错误),或者自己应用修补程序(您可能需要手动执行此操作,因为行号已稍微更改).
解决方法:
使用bundler来修补库是相对困难的(升级很容易,它们经常完成,路径被奇怪的数字污染 - 至少如果你使用边缘轨道;-),所以,而不是直接修补文件,您可能想在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
Run Code Online (Sandbox Code Playgroud)
并且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
Run Code Online (Sandbox Code Playgroud)
拥有这些文件,你有monkeypatched rake任务,你仍然可以轻松升级Rails.当然,您应该监视文件中引入的更改,activerecord/lib/active_record/railties/databases.rake
并确定是否仍需要进行修改.
归档时间: |
|
查看次数: |
8806 次 |
最近记录: |