1
|
#
|
2
|
# Convert/transfer data from production => development. This facilitates
|
3
|
# a conversion one database adapter type to another (say postgres -> mysql )
|
4
|
#
|
5
|
# WARNING 1: this script deletes all development data and replaces it with
|
6
|
# production data
|
7
|
#
|
8
|
# WARNING 2: This script assumes it is the only user updating either database.
|
9
|
# Database integrity could be corrupted if other users where
|
10
|
# writing to the databases.
|
11
|
#
|
12
|
# Usage: rake db:convert:prod2dev
|
13
|
#
|
14
|
# It assumes the development database has a schema identical to the production
|
15
|
# database, but will delete any data before importing the production data
|
16
|
#
|
17
|
# A couple of refinements added to Rama's script by M.Taylor:
|
18
|
# * Suppress single-table inheritance behaviour for tables containing a column named "type"
|
19
|
# * Do not copy column id if the table doesn't have one.
|
20
|
#
|
21
|
# A couple of the outer loops evolved from
|
22
|
# http://snippets.dzone.com/posts/show/3393
|
23
|
#
|
24
|
# For further instructions see
|
25
|
# http://myutil.com/2008/8/31/rake-task-transfer-rails-database-mysql-to-postgres
|
26
|
#
|
27
|
# The master repository for this script is at github:
|
28
|
# http://github.com/face/rails_db_convert_using_adapters/tree/master
|
29
|
#
|
30
|
#
|
31
|
# Author: Rama McIntosh
|
32
|
# Matson Systems, Inc.
|
33
|
# http://www.matsonsystems.com
|
34
|
#
|
35
|
# This rake task is released under this BSD license:
|
36
|
#
|
37
|
# Copyright (c) 2008, Matson Systems, Inc. All rights reserved.
|
38
|
#
|
39
|
# Redistribution and use in source and binary forms, with or without
|
40
|
# modification, are permitted provided that the following conditions
|
41
|
# are met:
|
42
|
#
|
43
|
# * Redistributions of source code must retain the above copyright
|
44
|
# notice, this list of conditions and the following disclaimer.
|
45
|
# * Redistributions in binary form must reproduce the above copyright
|
46
|
# notice, this list of conditions and the following disclaimer in the
|
47
|
# documentation and/or other materials provided with the distribution.
|
48
|
# * Neither the name of Matson Systems, Inc. nor the names of its
|
49
|
# contributors may be used to endorse or promote products derived
|
50
|
# from this software without specific prior written permission.
|
51
|
#
|
52
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
53
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
54
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
55
|
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
56
|
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
57
|
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
58
|
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
59
|
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
60
|
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
61
|
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
62
|
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
63
|
# POSSIBILITY OF SUCH DAMAGE.
|
64
|
|
65
|
# PAGE_SIZE is the number of rows updated in a single transaction.
|
66
|
# This facilitates tables where the number of rows exceeds the systems
|
67
|
# memory
|
68
|
PAGE_SIZE=10000
|
69
|
|
70
|
namespace :db do
|
71
|
namespace :convert do
|
72
|
desc 'Convert/import production data to development. DANGER Deletes all data in the development database. Assumes both schemas are already migrated.'
|
73
|
task :prod2dev => :environment do
|
74
|
|
75
|
# We need unique classes so ActiveRecord can hash different connections
|
76
|
# We do not want to use the real Model classes because any business
|
77
|
# rules will likely get in the way of a database transfer
|
78
|
class ProductionModelClass < ActiveRecord::Base
|
79
|
self.inheritance_column = :_type_disabled
|
80
|
end
|
81
|
class DevelopmentModelClass < ActiveRecord::Base
|
82
|
self.inheritance_column = :_type_disabled
|
83
|
end
|
84
|
|
85
|
skip_tables = ["schema_info", "schema_migrations"]
|
86
|
|
87
|
# Generate a list of all tables needing conversion
|
88
|
table_list = (ActiveRecord::Base.connection.tables - skip_tables).sort
|
89
|
|
90
|
# Use this line to convert just a specific list of tables
|
91
|
# table_list = ["custom_fields_trackers","custom_fields_projects","groups_users","projects_trackers"]
|
92
|
|
93
|
ActiveRecord::Base.establish_connection(:production)
|
94
|
|
95
|
table_list.each do |table_name|
|
96
|
|
97
|
ProductionModelClass.set_table_name(table_name)
|
98
|
DevelopmentModelClass.set_table_name(table_name)
|
99
|
DevelopmentModelClass.establish_connection(:development)
|
100
|
DevelopmentModelClass.reset_column_information
|
101
|
ProductionModelClass.reset_column_information
|
102
|
DevelopmentModelClass.record_timestamps = false
|
103
|
|
104
|
# Page through the data in case the table is too large to fit in RAM
|
105
|
offset = count = 0;
|
106
|
print "Converting #{table_name}..."; STDOUT.flush
|
107
|
# First, delete any old dev data
|
108
|
DevelopmentModelClass.delete_all
|
109
|
while ((models = ProductionModelClass.find(:all,
|
110
|
:offset=>offset, :limit=>PAGE_SIZE)).size > 0)
|
111
|
|
112
|
count += models.size
|
113
|
offset += PAGE_SIZE
|
114
|
|
115
|
# Now, write out the prod data to the dev db
|
116
|
DevelopmentModelClass.transaction do
|
117
|
models.each do |model|
|
118
|
new_model = DevelopmentModelClass.new(model.attributes)
|
119
|
if (model.attributes.has_key?('id'))
|
120
|
new_model.id = model.id
|
121
|
end
|
122
|
new_model.save(false)
|
123
|
end
|
124
|
end
|
125
|
end
|
126
|
print "#{count} records converted\n"
|
127
|
end
|
128
|
end
|
129
|
end
|
130
|
end
|