TL; DR请将您的数据迁移代码移至Rake任务或使用成熟的架构样式的gem。通过测试覆盖此逻辑。
我在FunBox担任后端开发人员。对于许多项目,我们正在编写Ruby On Rails后端。我们努力建立适当的开发流程,因此,当遇到问题时,我们会尝试理解问题并提出方法建议。数据迁移问题也发生了这种情况。一次,我在一个单独的包含测试的Rake任务中进行了数据迁移,然后团队提出了一个问题:“为什么不进行模式迁移?” 我在内部聊天中询问开发人员,令我惊讶的是,意见分歧很大。显然,这个问题是模棱两可的,值得深思熟虑的分析和一篇文章。当有人在代码审查中引用此文本的链接,以回答为什么要进行特定数据迁移或相反不进行模式迁移时,为我完成了每篇文章的最大目标计划。
抒情离题
我自己写这篇文章来减轻痛苦并提高团队生产力。一开始,我希望找到确凿的证据来证明将模式迁移误用于数据迁移的危险。与此同时,我正在阅读Nikolai Berdyaev的著作《创造力的意义》。为一个人辩护的经验。”从中我得到了“大教堂精神”的概念。
IT . Ruby, - . , , . , : , , , , , , .
, , . , , , , .
— , (views), , . .
— (, , , .) . . , . CI, , ( ) SQL , .
— . , DML- UPDATE
SQL. . .
(Continuous Delivery) — , .
Rails , , DDL-. , . , Rails omakase- . , .
, , . , . , , . .
. , . (, ) , .
, . . -, , .
deadlocks .
, , , Zero Downtime Migrations Strong Migrations.
— DSL (Domain Specific Language) Ruby DDL- SQL . DSL, , . , .
DSL, , SRP. . , , …
( , )
Ruby On Rails Data Migration , . , . Rails-, . .
SQL ORM ActiveRecord.
:
- . .
- , .
- callbacks , .
«» . , .
# db/migrate/20100513121110_add_flag_to_product.rb
class AddFlagToProduct < ActiveRecord::Migration
class Product < ActiveRecord::Base
end
def change
add_column :products, :flag, :boolean
Product.reset_column_information
Product.all.each do |product|
product.update_attributes!(:flag => false)
end
end
end
.
, each
find_each
c batch-.
SQL
, , SQL, :
- , . , , , (SQL), .
- JOIN-, , .
- , deadlock.
,
, .
, nullable- .
, .
, :
UPDATE table SET field = 'f' WHERE field IS NULL
:
class ClientDemandsMakeApprovedNullable < ActiveRecord::Migration
def up
change_column_null :client_demands, :approved, true
change_column_default :client_demands, :approved, nil
end
def down
execute("UPDATE client_demands SET approved = 'f' WHERE approved IS NULL")
change_column_null :client_demands, :approved, false
change_column_default :client_demands, :approved, false
end
end
, . , , . Dan Mayer Managing DB Schema & Data Changes Modifying Large Tables.
. «», . . , , , .
, .
, , .
, . . REPL .
, :
- ;
- ;
- .
. , . . .
, , , , .
Rake-
, — Rake-. . -.
Rake- . , . . . — .
, , Rake, Thoughtbot:
# lib/tasks/temporary/users.rake
namespace :users do
desc "Actualize achievements counter cache"
task actualize_achievements_counter_cache: :environment do
# C (ActiveRelation)
users = User.with_achievements
#
puts "Going to update #{users.count} users"
# , ,
# .
ActiveRecord::Base.transaction do
# Batch- find_each
users.find_each do |user|
#
user.actualize_achievements_counter_cache!
#
print "."
end
end
puts "Done!"
end
end
each
find_each
, . memory bloats. Akshay Mohite.
. , Rake- .
, . . , , . .
Mark Qualie up, . «» . :
class AddLastSmiledAtColumnToUsers < ActiveRecord::Migration[5.1]
def change
add_column :users, :last_smiled_at, :datetime
add_index :users, :last_smiled_at
end
class Data
def up
User.all.find_in_batches(batch_size: 250).each do |group|
ActiveRecord::Base.transaction do
group.each do |user|
user.last_smiled_at = user.smiles.last.created_at
user.save if user.changed?
end
end
end
end
end
end
:
Dir.glob("#{Rails.root}/db/migrate/*.rb").each { |file| require file }
AddLastSmiledAtColumnToUsers::Data.new.up
Job, .
, - , .
, , .
, . , .
data-migrate
(> 670), , Readme. Rails 5+.
, Rails 4+:
rails-data-migrations
(> 93 )
nonschema_migrations
(> 53 )
. .
, Rake-. . , .
db/data
, db/migrate
c :
rails g data_migration add_this_to_that
:
rake data:migrate
rake db:migrate:with_data
rake db:rollback:with_data
rake db:migrate:status:with_data
, .
Rails | Rake | ||||
---|---|---|---|---|---|
+ | - | - | - | - | |
Zero Downtime Deployment | - | + | + | + | + |
Test First | - | - | + | + | |
+ | - | - | + | ||
+ | - | + | + | + | |
+ | - | - | + | + |
.
— , :
- — ;
- Zero Downtime Deployment — , ;
- Test First — ;
- — ;
- — , ;
- — , , .
, Rake- — .
, . .
, — , . , .
- Rails Guides.
- Thoughtbot. Data Migrations in Rails.
- AtomicObject. Testing Data Migrations in Rails.
- Marcqualie. Rails Data Migrations.
- Ombulabs. Three Useful Data Migration Patterns for Rails.
- Strong Migrations.
- Zero Downtime Migrations.
- Dan Mayer. Managing DB Schema & Data Change.
Akshay Mohite find_each
each
.- . « . ». 1, 8 . , , .
UPD 2020-08-06: Extrapolator « ».
- , Test First .
.
UPD 2020-08-07: . , . . , .