data_migrate 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +78 -8
- data/lib/data_migrate/version.rb +1 -1
- data/lib/generators/data_migrate.rb +0 -7
- data/lib/generators/data_migration/data_migration_generator.rb +1 -1
- data/tasks/databases.rake +28 -7
- metadata +2 -5
- data/lib/generators/data_migrate/USAGE +0 -8
- data/lib/generators/data_migrate/install/install_generator.rb +0 -24
- data/lib/generators/data_migrate/install/templates/install_migration.rb +0 -13
data/README.md
CHANGED
|
@@ -3,25 +3,90 @@ Data Migrate
|
|
|
3
3
|
|
|
4
4
|
Run data migrations alongside schema migrations.
|
|
5
5
|
|
|
6
|
-
Data migrations are stored in db/data. They act like schema
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
Data migrations are stored in db/data. They act like schema
|
|
7
|
+
migrations, except they should be reserved for data migrations. For
|
|
8
|
+
instance, if you realize you need to titleize all yours titles, this
|
|
9
|
+
is the place to do it.
|
|
10
|
+
|
|
11
|
+
Why should I use this?
|
|
12
|
+
----------------------
|
|
13
|
+
|
|
14
|
+
Its seems when a project hits a certain size, I get to manipulate data
|
|
15
|
+
outside the application itself. Changing defaults, new validations,
|
|
16
|
+
one-to-one to one-to-many... I found it a pain and dodgy to have to
|
|
17
|
+
step up migrations one by one, run a ruby script of some sort, then
|
|
18
|
+
resume migrations. It tanks a lot of the automation of deploy.
|
|
19
|
+
|
|
20
|
+
If you don't use the one off scripts, you could do it as a regular
|
|
21
|
+
migration. It'd be much better to keep concerns separate. The benefit
|
|
22
|
+
of having them separate has to do with your data model.
|
|
23
|
+
|
|
24
|
+
For instance, lets take an absurd example, to illustrate: You have
|
|
25
|
+
your infamous [Rails blog](http://media.rubyonrails.org/video/rails-0-5.mov)
|
|
26
|
+
that has posts with many comments. After some use, you decide you are
|
|
27
|
+
going to be a trend setter, and want only one comment per post, and
|
|
28
|
+
just the text. "Frist!" rules the day. Given that you:
|
|
29
|
+
- write a migration to add a comment column to Post
|
|
30
|
+
- write a migration to move the contents of the first comments to the Post
|
|
31
|
+
- drop the column_id column from Post
|
|
32
|
+
- drop the Comment model
|
|
33
|
+
- fix all your test/controller/view mojo.
|
|
34
|
+
|
|
35
|
+
You've just got bit. When you rake setup:development, the mess gets
|
|
36
|
+
mad at you after it creates your database, and starts cranking through
|
|
37
|
+
migrations. It gets to the part where you iterate over the comments
|
|
38
|
+
and it blows up. You don't have a comment model anymore for it to
|
|
39
|
+
even try and get 'all' from. You think you are smarter, and wrap the
|
|
40
|
+
AR call in a conditional based on the environment. That's fine until
|
|
41
|
+
you get that QA gal, and she wants her own thing. Then the UI people
|
|
42
|
+
get tired of waiting for the full stack to load on page refreshes, so
|
|
43
|
+
you have to edit past migrations...
|
|
44
|
+
|
|
45
|
+
With Data Migrate, you have the control. You can generate your
|
|
46
|
+
migrations as schema or data as you would as your work flow. For
|
|
47
|
+
setting tasks that don't require any intermediate AR activity, like
|
|
48
|
+
dev and test, you stick with db:migrate. For your prod, and qa, you
|
|
49
|
+
change their scripts to `db:migrate:with_data`. Of course you want to
|
|
50
|
+
test your migration, so you have the choice of `db:migrate:with_data` or
|
|
51
|
+
`data:migrate` to just capture that data change.
|
|
52
|
+
|
|
53
|
+
What's it do?
|
|
54
|
+
-------------
|
|
55
|
+
|
|
56
|
+
Data migrations are stored in db/data. They act like schema
|
|
57
|
+
migrations, except they should be reserved for data migrations. For
|
|
58
|
+
instance, if you realize you need to titleize all yours titles, this
|
|
59
|
+
is the place to do it. Running any of the provided rake tasks also
|
|
60
|
+
creates a data schema table to mirror the usual schema migrations
|
|
61
|
+
table to track all the goodness.
|
|
62
|
+
|
|
63
|
+
Data migrations can be created at the same time as schema migrations,
|
|
64
|
+
or independently. Database (db:) tasks have been added and extended
|
|
65
|
+
to run on data migrations only, or in conjunction with the schema
|
|
66
|
+
migration. For instance, `rake db:migrate:with_data` will run both
|
|
67
|
+
schema and data migrations in the proper order.
|
|
9
68
|
|
|
10
69
|
Note: If a data and schema migration share the same version number, schema gets precedence when migrating up. Data does down.
|
|
11
70
|
|
|
12
71
|
Rails 3 and Ruby 1.9
|
|
13
72
|
--------------------
|
|
14
73
|
|
|
15
|
-
Data Migrate is Rails 3.0.0 - 3.0.7,
|
|
74
|
+
Data Migrate is Rails 3.0.0 - 3.0.7, and Ruby 1.9 compatible
|
|
16
75
|
|
|
17
76
|
Installation
|
|
18
77
|
------------
|
|
19
|
-
|
|
78
|
+
Add the gem to your project
|
|
79
|
+
|
|
80
|
+
# Gemfile
|
|
81
|
+
gem 'data_migrate'
|
|
20
82
|
|
|
21
|
-
|
|
22
|
-
rake db:migrate
|
|
83
|
+
Then `bundle install` and you are ready to go.
|
|
23
84
|
|
|
24
|
-
|
|
85
|
+
So you know, when you use one of the provide rake tasks, a table
|
|
86
|
+
called 'data_migrations' will be created in your database. This
|
|
87
|
+
is to mirror the way the standard 'db' rake tasks work. If you've
|
|
88
|
+
installed previous to v1.1.0, you'll want to delete the
|
|
89
|
+
'create\_data\_migrations_table' migration.
|
|
25
90
|
|
|
26
91
|
Usage
|
|
27
92
|
-----
|
|
@@ -76,3 +141,8 @@ Running `rake db:migrate:up:with_data VERSION=20110419021211` would execute the
|
|
|
76
141
|
Going down instead of up would be the opposite.
|
|
77
142
|
|
|
78
143
|
`rake db:migrate:status:with_data` provides and additional column to indicate which type of migration.
|
|
144
|
+
|
|
145
|
+
Thanks
|
|
146
|
+
------
|
|
147
|
+
[Jeremy Durham](http://jeremydurham.com/) for fleshing out the idea with me, and providing guidance.
|
|
148
|
+
You! Yes, you. Thanks for checking it out.
|
data/lib/data_migrate/version.rb
CHANGED
|
@@ -1,13 +1,6 @@
|
|
|
1
|
-
require 'rails/generators/base'
|
|
2
1
|
require 'rails/generators/named_base'
|
|
3
2
|
module DataMigrate
|
|
4
3
|
module Generators
|
|
5
|
-
class InstallGenerator < Rails::Generators::Base #:nodoc:
|
|
6
|
-
def self.source_root
|
|
7
|
-
@_data_migrate_source_root ||= File.expand_path(File.join(File.dirname(__FILE__), 'data_migrate', generator_name, 'templates'))
|
|
8
|
-
end
|
|
9
|
-
end
|
|
10
|
-
|
|
11
4
|
class DataMigrationGenerator < Rails::Generators::NamedBase #:nodoc:
|
|
12
5
|
def self.source_root
|
|
13
6
|
@_data_migrate_source_root ||= File.expand_path(File.join(File.dirname(__FILE__), generator_name, 'templates'))
|
|
@@ -9,7 +9,7 @@ module DataMigrate
|
|
|
9
9
|
include Rails::Generators::Migration
|
|
10
10
|
|
|
11
11
|
argument :attributes, :type => :array, :default => [], :banner => "field:type field:type"
|
|
12
|
-
class_option :skip_schema_migration, :desc => 'Dont generate database migration file.', :type => :boolean
|
|
12
|
+
class_option :skip_schema_migration, :desc => 'Dont generate database schema migration file.', :type => :boolean
|
|
13
13
|
|
|
14
14
|
def create_data_migration
|
|
15
15
|
set_local_assigns!
|
data/tasks/databases.rake
CHANGED
|
@@ -2,8 +2,7 @@ namespace :db do
|
|
|
2
2
|
namespace :migrate do
|
|
3
3
|
desc "Migrate the database data and schema (options: VERSION=x, VERBOSE=false)."
|
|
4
4
|
task :with_data => :environment do
|
|
5
|
-
|
|
6
|
-
next unless config
|
|
5
|
+
assure_data_schema_table
|
|
7
6
|
|
|
8
7
|
ActiveRecord::Migration.verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] == "true" : true
|
|
9
8
|
target_version = ENV["VERSION"] ? ENV["VERSION"].to_i : nil
|
|
@@ -60,6 +59,7 @@ namespace :db do
|
|
|
60
59
|
namespace :redo do
|
|
61
60
|
desc 'Rollbacks the database one migration and re migrate up (options: STEP=x, VERSION=x).'
|
|
62
61
|
task :with_data => :environment do
|
|
62
|
+
assure_data_schema_table
|
|
63
63
|
if ENV["VERSION"]
|
|
64
64
|
Rake::Task["db:migrate:down:with_data"].invoke
|
|
65
65
|
Rake::Task["db:migrate:up:with_data"].invoke
|
|
@@ -75,7 +75,7 @@ namespace :db do
|
|
|
75
75
|
task :with_data => :environment do
|
|
76
76
|
version = ENV["VERSION"] ? ENV["VERSION"].to_i : nil
|
|
77
77
|
raise "VERSION is required" unless version
|
|
78
|
-
|
|
78
|
+
assure_data_schema_table
|
|
79
79
|
run_both = ENV["BOTH"] == "true"
|
|
80
80
|
migrations = pending_migrations.keep_if{|m| m[:version] == version}
|
|
81
81
|
|
|
@@ -100,7 +100,7 @@ namespace :db do
|
|
|
100
100
|
task :with_data => :environment do
|
|
101
101
|
version = ENV["VERSION"] ? ENV["VERSION"].to_i : nil
|
|
102
102
|
raise "VERSION is required" unless version
|
|
103
|
-
|
|
103
|
+
assure_data_schema_table
|
|
104
104
|
run_both = ENV["BOTH"] == "true"
|
|
105
105
|
migrations = past_migrations.keep_if{|m| m[:version] == version}
|
|
106
106
|
|
|
@@ -170,8 +170,7 @@ namespace :db do
|
|
|
170
170
|
desc 'Rolls the schema back to the previous version (specify steps w/ STEP=n).'
|
|
171
171
|
task :with_data => :environment do
|
|
172
172
|
step = ENV['STEP'] ? ENV['STEP'].to_i : 1
|
|
173
|
-
|
|
174
|
-
next unless config
|
|
173
|
+
assure_data_schema_table
|
|
175
174
|
past_migrations[0..(step - 1)].each do | past_migration |
|
|
176
175
|
if past_migration[:kind] == :data
|
|
177
176
|
ActiveRecord::Migration.write("== %s %s" % ['Data', "=" * 71])
|
|
@@ -187,6 +186,7 @@ namespace :db do
|
|
|
187
186
|
namespace :forward do
|
|
188
187
|
desc 'Pushes the schema to the next version (specify steps w/ STEP=n).'
|
|
189
188
|
task :with_data => :environment do
|
|
189
|
+
assure_data_schema_table
|
|
190
190
|
# TODO: No worky for .forward
|
|
191
191
|
step = ENV['STEP'] ? ENV['STEP'].to_i : 1
|
|
192
192
|
# DataMigrate::DataMigrator.forward('db/data/', step)
|
|
@@ -206,6 +206,7 @@ namespace :db do
|
|
|
206
206
|
namespace :version do
|
|
207
207
|
desc "Retrieves the current schema version numbers for data and schema migrations"
|
|
208
208
|
task :with_data => :environment do
|
|
209
|
+
assure_data_schema_table
|
|
209
210
|
puts "Current Schema version: #{ActiveRecord::Migrator.current_version}"
|
|
210
211
|
puts "Current Data version: #{DataMigrate::DataMigrator.current_version}"
|
|
211
212
|
end
|
|
@@ -214,6 +215,7 @@ end
|
|
|
214
215
|
|
|
215
216
|
namespace :data do
|
|
216
217
|
task :migrate => :environment do
|
|
218
|
+
assure_data_schema_table
|
|
217
219
|
ActiveRecord::Migration.verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] == "true" : true
|
|
218
220
|
DataMigrate::DataMigrator.migrate("db/data/", ENV["VERSION"] ? ENV["VERSION"].to_i : nil)
|
|
219
221
|
end
|
|
@@ -221,6 +223,7 @@ namespace :data do
|
|
|
221
223
|
namespace :migrate do
|
|
222
224
|
desc 'Rollbacks the database one migration and re migrate up (options: STEP=x, VERSION=x).'
|
|
223
225
|
task :redo => :environment do
|
|
226
|
+
assure_data_schema_table
|
|
224
227
|
if ENV["VERSION"]
|
|
225
228
|
Rake::Task["data:migrate:down"].invoke
|
|
226
229
|
Rake::Task["data:migrate:up"].invoke
|
|
@@ -232,6 +235,7 @@ namespace :data do
|
|
|
232
235
|
|
|
233
236
|
desc 'Runs the "up" for a given migration VERSION.'
|
|
234
237
|
task :up => :environment do
|
|
238
|
+
assure_data_schema_table
|
|
235
239
|
version = ENV["VERSION"] ? ENV["VERSION"].to_i : nil
|
|
236
240
|
raise "VERSION is required" unless version
|
|
237
241
|
DataMigrate::DataMigrator.run(:up, "db/data/", version)
|
|
@@ -241,6 +245,7 @@ namespace :data do
|
|
|
241
245
|
task :down => :environment do
|
|
242
246
|
version = ENV["VERSION"] ? ENV["VERSION"].to_i : nil
|
|
243
247
|
raise "VERSION is required" unless version
|
|
248
|
+
assure_data_schema_table
|
|
244
249
|
DataMigrate::DataMigrator.run(:down, "db/data/", version)
|
|
245
250
|
end
|
|
246
251
|
|
|
@@ -277,14 +282,16 @@ namespace :data do
|
|
|
277
282
|
|
|
278
283
|
desc 'Rolls the schema back to the previous version (specify steps w/ STEP=n).'
|
|
279
284
|
task :rollback => :environment do
|
|
285
|
+
assure_data_schema_table
|
|
280
286
|
step = ENV['STEP'] ? ENV['STEP'].to_i : 1
|
|
281
287
|
DataMigrate::DataMigrator.rollback('db/data/', step)
|
|
282
288
|
end
|
|
283
289
|
|
|
284
290
|
desc 'Pushes the schema to the next version (specify steps w/ STEP=n).'
|
|
285
291
|
task :forward => :environment do
|
|
286
|
-
|
|
292
|
+
assure_data_schema_table
|
|
287
293
|
step = ENV['STEP'] ? ENV['STEP'].to_i : 1
|
|
294
|
+
# TODO: No worky for .forward
|
|
288
295
|
# DataMigrate::DataMigrator.forward('db/data/', step)
|
|
289
296
|
migrations = pending_data_migrations.reverse.pop(step).reverse
|
|
290
297
|
migrations.each do | pending_migration |
|
|
@@ -294,6 +301,7 @@ namespace :data do
|
|
|
294
301
|
|
|
295
302
|
desc "Retrieves the current schema version number for data migrations"
|
|
296
303
|
task :version => :environment do
|
|
304
|
+
assure_data_schema_table
|
|
297
305
|
puts "Current data version: #{DataMigrate::DataMigrator.current_version}"
|
|
298
306
|
end
|
|
299
307
|
end
|
|
@@ -342,3 +350,16 @@ def past_migrations sort=nil
|
|
|
342
350
|
|
|
343
351
|
sort == 'asc' ? sort_migrations(migrations) : sort_migrations(migrations).reverse
|
|
344
352
|
end
|
|
353
|
+
|
|
354
|
+
def assure_data_schema_table
|
|
355
|
+
config = ActiveRecord::Base.configurations[Rails.env || 'development']
|
|
356
|
+
ActiveRecord::Base.establish_connection(config)
|
|
357
|
+
sm_table = DataMigrate::DataMigrator.schema_migrations_table_name
|
|
358
|
+
|
|
359
|
+
unless ActiveRecord::Base.connection.table_exists?(sm_table)
|
|
360
|
+
ActiveRecord::Base.connection.create_table(sm_table, :id => false) do |schema_migrations_table|
|
|
361
|
+
schema_migrations_table.column :version, :string, :null => false
|
|
362
|
+
end
|
|
363
|
+
ActiveRecord::Base.connection.add_index sm_table, :version, :unique => true, :name => "#{ActiveRecord::Base.table_name_prefix}unique_data_migrations#{ActiveRecord::Base.table_name_suffix}"
|
|
364
|
+
end
|
|
365
|
+
end
|
metadata
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: data_migrate
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease:
|
|
5
|
-
version: 1.
|
|
5
|
+
version: 1.1.0
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
8
8
|
- Andrew J Vargo
|
|
@@ -10,7 +10,7 @@ autorequire:
|
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
12
|
|
|
13
|
-
date: 2011-05-
|
|
13
|
+
date: 2011-05-05 00:00:00 Z
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|
|
16
16
|
name: rails
|
|
@@ -47,9 +47,6 @@ files:
|
|
|
47
47
|
- lib/data_migrate/railtie.rb
|
|
48
48
|
- lib/data_migrate/version.rb
|
|
49
49
|
- lib/generators/data_migrate.rb
|
|
50
|
-
- lib/generators/data_migrate/USAGE
|
|
51
|
-
- lib/generators/data_migrate/install/install_generator.rb
|
|
52
|
-
- lib/generators/data_migrate/install/templates/install_migration.rb
|
|
53
50
|
- lib/generators/data_migration/data_migration_generator.rb
|
|
54
51
|
- lib/generators/data_migration/templates/data_migration.rb
|
|
55
52
|
- lib/generators/data_migration/templates/migration.rb
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
require 'generators/data_migrate'
|
|
2
|
-
require 'rails/generators'
|
|
3
|
-
require 'rails/generators/migration'
|
|
4
|
-
|
|
5
|
-
module DataMigrate
|
|
6
|
-
module Generators
|
|
7
|
-
class InstallGenerator < Rails::Generators::Base
|
|
8
|
-
include Rails::Generators::Migration
|
|
9
|
-
|
|
10
|
-
def create_migration_file
|
|
11
|
-
migration_template "install_migration.rb", "db/migrate/create_data_migrations.rb"
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
protected
|
|
15
|
-
def self.next_migration_number(dirname)
|
|
16
|
-
if ActiveRecord::Base.timestamped_migrations
|
|
17
|
-
Time.new.utc.strftime("%Y%m%d%H%M%S")
|
|
18
|
-
else
|
|
19
|
-
"%.3d" % (current_migration_number(dirname) + 1)
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
end
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
class CreateDataMigrations < ActiveRecord::Migration
|
|
2
|
-
def self.up
|
|
3
|
-
create_table :data_migrations do |t|
|
|
4
|
-
t.string :version, :null => false
|
|
5
|
-
end
|
|
6
|
-
|
|
7
|
-
add_index :data_migrations, :version, :unique => true, :name => "<%= ActiveRecord::Base.table_name_prefix %>unique_data_migrations<%= ActiveRecord::Base.table_name_suffix %>"
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
def self.down
|
|
11
|
-
drop_table :data_migrations
|
|
12
|
-
end
|
|
13
|
-
end
|