Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 282 lines (214 sloc) 10.159 kB
5e9ab11 @rsandor First commit
authored
1 Migrate - A database agnostic migration system for Node.js
2 ================================================================================
3
4 By Ryan Sandor Richards
5
6 Introduction
7 --------------------------------------------------------------------------------
8 Migrate is a tool for Node.js applications that allows for the programmatic
9 definition of database schema changes. It borrows very heavily from the Rails
10 migration system and contains many of the same features. If you are unfamiliar
11 with how migrations work don't fret, just read on and everything will be
12 explained!
13
14 Requirements
15 --------------------------------------------------------------------------------
16 1. Node.js - http://github.com/ry/node
17 2. node-mysql - http://github.com/masuidrive/node-mysql
18
19 Please note that at the current time we only support MySQL but other DBMS' are
20 on their way (next up: Postgres).
21
22 Installation
23 --------------------------------------------------------------------------------
24 1. Download the Migrate source - http://github.com/rsandor/node-migrate
25 2. Fill out the supplied "config.js"
26
27 Where, exactly, you include the migrate source in your project matters very
28 little as long as both migrate.js and config.js are in the same directory and
29 the node-mysql and migration paths in the configuration file are relative to
30 the directory where the migrate.js file resides.
31
32 How do I use migrate?
33 --------------------------------------------------------------------------------
34 Once you have the configuration file filled you you can create a new migration
35 from the command line:
36
036dd24 @rsandor Fixed a couple markdown issues.
authored
37 `node migrate.js create create_users_table`
5e9ab11 @rsandor First commit
authored
38
39 This command will create a blank migration and stick it in the migrations folder
40 that you supplied in the configuration file. Once you fill out the migration's
41 up and down functions you can then apply the migration to your schema like so:
42
036dd24 @rsandor Fixed a couple markdown issues.
authored
43 `node migrate.js migrate`
5e9ab11 @rsandor First commit
authored
44
45 That command will determine if there are any migrations that have not been
46 applied and apply them sequentially until they are all done or one of them
47 fails.
48
d2f35fc @rsandor More markdown fixes.
authored
49 If you wish to roll back any migrations that's super simple too, just use:
5e9ab11 @rsandor First commit
authored
50
036dd24 @rsandor Fixed a couple markdown issues.
authored
51 `node migrate.js rollback`
5e9ab11 @rsandor First commit
authored
52
53 By default this will roll back only a single migration, but you can provide
54 a numeric parameter to tell it how many migrations you'd like it to roll back.
55 For instance, here's how you would roll back five migrations:
56
036dd24 @rsandor Fixed a couple markdown issues.
authored
57 `node migrate.js rollback 5`
5e9ab11 @rsandor First commit
authored
58
59 What is a migration?
60 --------------------------------------------------------------------------------
61 A migration is a programmatic way of defining incremental database schema
62 changes. It has an "up" method for describing how to apply the changes, and a
63 "down" method for removing them. Here is an example migration:
aecb0aa @rsandor More markdown fixes.
authored
64 var create_users_table = new Migration({
65 up: function() {
66 this.create_table('users', function(t) {
67 t.integer('id');
68 t.string('email');
69 t.string('password');
70 t.primary_key('id');
71 });
72 },
73 down: function() {
74 this.drop_table('users');
75 }
76 });
5e9ab11 @rsandor First commit
authored
77 In the above migration the "up" function creates a table named "users" with
78 three fields (id, email, and password) and a primary key on id. The "down"
79 function reverses these changes and simply drops the entire "users" table.
80
81 When you run the migration it gets converted into a collection of database
82 agnostic objects which are then translated into SQL for the appropriate DBMS.
83
84 What can I do in a migration?
85 --------------------------------------------------------------------------------
86 The "up" and "down" methods of a migration support the exact same set of methods
87 . This means you can create and destroy schema information in both methods. The
88 Migration object supports the following methods:
89
90 ### create_table(name, body)
91
92 This method creates a table with the given name and passes the newly created table
93 representation to the supplied `body` closure.
94 From within the body closure one can execute methods on the table to add columns
95 and indices. Here is a complete list of all the "table" methods available:
96
97 * `t.column(name, type, options)` - Creates a column with the given name, type
98 and additional options. Additional options include: `limit`, `not_null`,
99 `precision`, `scale`, and `default_value`. `limit` controls the number of
100 bytes to use for the integer type, `not_null` is used to determine if the
101 column is allowed to be null, `precision` and `scale` are used for the
102 decimal data type, and `default_value` allows you to set the default value
103 for the column.
104 * `t.primary_key(name)` - Sets the primary key for the table to the column with
105 the given name.
106 * `t.index(name)` - Sets an index on the table for the column with the given name
107
108 Finally the body also contains shortcut functions for each abstract data-type
109 tracked by Migrate. Each function has the form `t.type(name, options)` where name
110 and options are as explained in the `t.column` method. Here's a complete list:
111
112 * `string`, `text`, `integer`, `float`, `decimal`, `datetime`, `timestamp`, `time`,
113 `date`, `binary`, `boolean`
114
115 Example:
aecb0aa @rsandor More markdown fixes.
authored
116 this.create_table('high_scores', function(t) {
117 t.integer('id');
118 t.string('name', {limit: 32});
119 t.create('score', 'integer', {limit: 8})
120 t.datetime('date');
121 t.primary_key('id');
122 t.index('name');
123 });
5e9ab11 @rsandor First commit
authored
124 Producing SQL:
aecb0aa @rsandor More markdown fixes.
authored
125 CREATE TABLE high_scores (
126 id INT,
127 name VARCHAR(32),
128 score BIGINT,
129 date DATETIME,
130 PRIMARY KEY (id),
131 INDEX (name)
132 );
5e9ab11 @rsandor First commit
authored
133
134 ### drop_table(name)
135 Simply drops a table from the schema. Example:
136
d2f35fc @rsandor More markdown fixes.
authored
137 `this.drop_table('high_scores');`
5e9ab11 @rsandor First commit
authored
138
861bb76 @rsandor Minor fixes to the create migration routine and the configuration file.
authored
139 Producing SQL:
5e9ab11 @rsandor First commit
authored
140
d2f35fc @rsandor More markdown fixes.
authored
141 `DROP_TABLE high_scores;`
5e9ab11 @rsandor First commit
authored
142
143 ### rename_table(old_name, new_name)
144 Renames a table. Example:
145
d2f35fc @rsandor More markdown fixes.
authored
146 `this.rename_table('high_scores', 'all_time_high_scores');`
5e9ab11 @rsandor First commit
authored
147
148 Producing SQL:
149
d2f35fc @rsandor More markdown fixes.
authored
150 `RENAME TABLE high_scores TO all_time_high_scores;`
5e9ab11 @rsandor First commit
authored
151
152 ### change_table(name, body)
153
154 Has all of the same functionality as `create_table` except it is used to
155 modify existing tables and adds the following functionality to body method:
156
157 * `t.rename(old_name, new_column)` - Renames and alters a column.
158 * `t.change(name, type, options)` - Alters a column without changing its name.
159 * `t.remove(name)` - Removes a column from the table.
160 * `t.remove_index(name)` - Removes an index from the table.
161 * `t.remove_primary_key()` - Removes a primary key from the table.
162
163 Example:
aecb0aa @rsandor More markdown fixes.
authored
164 this.change_table('all_time_high_scores', function(t) {
165 t.remove_index('name');
166 t.remove_primary_key();
167 t.remove('date');
168 t.date('date');
169 t.rename('score' {
170 name: 'high_score',
171 type: 'integer',
172 limit: 4
173 });
174 t.change('name', 'string' {limit: 128});
5e9ab11 @rsandor First commit
authored
175 });
176 Producing SQL:
aecb0aa @rsandor More markdown fixes.
authored
177 ALTER TABLE all_time_high_scores
178 DROP INDEX (name),
179 DROP PRIMARY KEY,
180 DROP COLUMN 'date',
181 ADD COLUMN date DATE,
182 CHANGE COLUMN score high_score INT,
183 MODIFY COLUMN name VARCHAR(128);
5e9ab11 @rsandor First commit
authored
184
185 ### add_column(table_name, column_name, type, options)
186 Adds a column to a table. Example:
187
d2f35fc @rsandor More markdown fixes.
authored
188 `this.add_column('all_time_high_scores', 'comment', 'string', {limit: 512});`
5e9ab11 @rsandor First commit
authored
189
190 Producing SQL:
191
d2f35fc @rsandor More markdown fixes.
authored
192 `ALTER TABLE all_time_high_scores ADD COLUMN comment VARCHAR(512);`
5e9ab11 @rsandor First commit
authored
193
194 ### rename_column(table_name, column_name, new_column)
195 Renames and modifies a column in a table. Example:
aecb0aa @rsandor More markdown fixes.
authored
196 this.rename('all_time_high_scores', 'high_score', {
197 name: 'score',
198 type: 'integer',
199 limit: 8
200 });
5e9ab11 @rsandor First commit
authored
201 Producing SQL:
aecb0aa @rsandor More markdown fixes.
authored
202 ALTER TABLE all_time_high_scores CHANGE COLUMN high_score score BIGINT;
5e9ab11 @rsandor First commit
authored
203
204 ### change_column(table_name, column_name, type, options)
205 Changes a column's definition. Example:
206
d2f35fc @rsandor More markdown fixes.
authored
207 `this.change_column('all_time_high_scores', 'comment', 'text');`
5e9ab11 @rsandor First commit
authored
208
209 Producing SQL:
210
d2f35fc @rsandor More markdown fixes.
authored
211 `ALTER TABLE all_time_high_scores MODIFY COLUMN comment TEXT;`
5e9ab11 @rsandor First commit
authored
212
213 ### remove_column(table_name, column_name)
214 Removes a column from a table. Example:
215
d2f35fc @rsandor More markdown fixes.
authored
216 `this.remove_column('all_time_high_scores', 'date');`
5e9ab11 @rsandor First commit
authored
217
218 Producing SQL:
219
d2f35fc @rsandor More markdown fixes.
authored
220 `ALTER TABLE all_time_high_scores DROP COLUMN date;`
5e9ab11 @rsandor First commit
authored
221
222 ### add_index(table_name, column_name, options)
223 Adds an index to a table. Example:
224
d2f35fc @rsandor More markdown fixes.
authored
225 `this.add_index('all_time_high_scores', 'id');`
5e9ab11 @rsandor First commit
authored
226
227 Producing SQL:
228
d2f35fc @rsandor More markdown fixes.
authored
229 `ALTER TABLE all_time_high_scores ADD INDEX (id);`
5e9ab11 @rsandor First commit
authored
230
231 ### remove_index(table_name, index_name)
232 Removes an index from a table. Example:
233
d2f35fc @rsandor More markdown fixes.
authored
234 `this.remove_index('id');`
5e9ab11 @rsandor First commit
authored
235
236 Producing SQL:
237
d2f35fc @rsandor More markdown fixes.
authored
238 `ALTER TABLE all_time_high_scores DROP INDEX (id);`
5e9ab11 @rsandor First commit
authored
239
240 ### execute(sql)
241 Executes arbitrary SQL. Example:
242
d2f35fc @rsandor More markdown fixes.
authored
243 `this.execute('insert into all_time_high_scores (name, score) values ('Ryan', 100000000);');`
5e9ab11 @rsandor First commit
authored
244
245 Producing SQL:
246
d2f35fc @rsandor More markdown fixes.
authored
247 `insert into all_time_high_scores (name, score) values ('Ryan', 100000000);`
5e9ab11 @rsandor First commit
authored
248
249 Outtro
250 --------------------------------------------------------------------------------
251 So that about sums it up. Simple and easy ;). It's a very early alpha version so
252 please don't hate on only having MySQL support! Things should be progressing
253 super rapidly, so keep an eye out. If you have a feature request feel free to
254 send me a message and I'll try to get it in ASAP.
255
256 Thanks!
257
258 License and Legalese
259 --------------------------------------------------------------------------------
260
261 Copyright (c) 2010 Ryan Sandor Richards
262
263 Permission is hereby granted, free of charge, to any person
264 obtaining a copy of this software and associated documentation
265 files (the "Software"), to deal in the Software without
266 restriction, including without limitation the rights to use,
267 copy, modify, merge, publish, distribute, sublicense, and/or sell
268 copies of the Software, and to permit persons to whom the
269 Software is furnished to do so, subject to the following
270 conditions:
271
272 The above copyright notice and this permission notice shall be
273 included in all copies or substantial portions of the Software.
274
275 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
276 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
277 OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
278 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
279 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
280 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
281 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
282 OTHER DEALINGS IN THE SOFTWARE.
Something went wrong with that request. Please try again.