Migration won't rollback to specific version?

Hi all,

I’m confused about how migrations work. I’ve been using them for a
couple of weeks but haven’t had any serious rollback issues yet. Just
now I added a field to a table with a migration and ran “rake migrate”,
which added the field as expected.

This was in the file db/migrate/007_mymigration.rb, making it version 7.

Later I changed my mind and decided to rollback to the previous schema,
so what I entered was

rake migrate VERSION=006

…which proceeded to drop all the tables in my database.

Now what I’d like to happen is (a) to understand why that happened, and
(b) to be able to run “rake migrate” and have it consecutively run each
migration 001 through 006 in turn and update the database.

I’ve tried running “rake migrate” again, thinking it would bring
everything up to date, but it seems the only migration it ran was 007,
which failed because the relevant table doesn’t exist.

I even deleted the schema_info table, thinking that Rails would
re-create and start at migration 001, but it behaved the same way.

What am I missing? Is this the correct behavior and I’m doing something
wrong? Fortunately this was on my development database where all I lost
was some test data.

Thanks,
Jeff

You may have to adjust the level of your version in the schema_info
table.

go to the mysql prompt or phpmyadmin, and check what the value is:

your_app> mysql -u root your_dbname_development

mysql> explain schema_info;

you will see there is one row one column called version.

then see what the version value is:

mysql> select * from schema_info;

±--------+
| version |
±--------+
| 7 |
±--------+

It will show you what your version number is really set to.
Set it to 0 and run Rake Migrate.

mysql> update schema_info set version = 0 where 1;

you can set the version to any number using this, but your tables must
be in sync with that number.

You can drop all of your other tables if you want to start from scratch.

This will not preserve any data you have in your tables.

-Sean

Jeff C.man wrote:

Hi all,

I’m confused about how migrations work. I’ve been using them for a
couple of weeks but haven’t had any serious rollback issues yet. Just
now I added a field to a table with a migration and ran “rake migrate”,
which added the field as expected.

This was in the file db/migrate/007_mymigration.rb, making it version 7.

Later I changed my mind and decided to rollback to the previous schema,
so what I entered was

rake migrate VERSION=006

…which proceeded to drop all the tables in my database.

Now what I’d like to happen is (a) to understand why that happened, and
(b) to be able to run “rake migrate” and have it consecutively run each
migration 001 through 006 in turn and update the database.

I’ve tried running “rake migrate” again, thinking it would bring
everything up to date, but it seems the only migration it ran was 007,
which failed because the relevant table doesn’t exist.

I even deleted the schema_info table, thinking that Rails would
re-create and start at migration 001, but it behaved the same way.

What am I missing? Is this the correct behavior and I’m doing something
wrong? Fortunately this was on my development database where all I lost
was some test data.

Thanks,
Jeff

sean lynch wrote:

You can drop all of your other tables if you want to start from scratch.

This will not preserve any data you have in your tables.

-Sean

I actually did this, I even completely dropped all the tables from my
schema, including the schema_info table.

Still it only attempts to run the most recent migration, which fails
because those tables don’t exist.

Are there any other factors influencing this?

Jeff

Jeff C.man wrote:

sean lynch wrote:

You can drop all of your other tables if you want to start from scratch.

This will not preserve any data you have in your tables.

-Sean

I actually did this, I even completely dropped all the tables from my
schema, including the schema_info table.

Still it only attempts to run the most recent migration, which fails
because those tables don’t exist.

Are there any other factors influencing this?

Jeff

I just tried creating a brand new rails app and a fresh database schema,
to test this out.

I ran “rails funky” to create a new app called “funky”, edited my
database.yml to associate it to a schema called “funk_development”, and
ran “ruby script/generate migration item”.

Then I created the follow two simple migration files in db/migrate:

001_item.rb:

class Item < ActiveRecord::Migration
def self.up
create_table :item do |table|
table.column :name, :string
table.column :price, :integer, :limit => 4
end
end

def self.down
drop_table :item
end
end

002_item.rb

class Item < ActiveRecord::Migration
def self.up
add_column :item, :description, :text
end

def self.down
remove_column :item, :description
end
end

According to all the documentation I’ve seen, running this on an empty
database should first run 001_item.rb and then 002_item.rb, creating and
updating the schema_info table with the current version number (2).

This is what happened:

C:\rails\funky>rake migrate
(in C:/rails/funky)
== Item: migrating

– add_column(:item, :description, :text)
rake aborted!
Mysql::Error: #42S02Table ‘funky_development.item’ doesn’t exist: ALTER
TABLE it
em ADD description text

(See full trace by running task with --trace)

Again it ran only the most recent migration, ignoring the first. The
“schema_info” table was created but when the migration failed its
version remained set at 0.

Anyone have any ideas? I have not been able to get migration on
multiple migration files to perform as described with even the most
simple trivial examples.

Am I misunderstanding how it should work? What’s going on here?

Thanks again,
Jeff C.man

Jeff C.man wrote:

Anyone have any ideas? I have not been able to get migration on
multiple migration files to perform as described with even the most
simple trivial examples.

Am I misunderstanding how it should work? What’s going on here?

Just a further note–I mistyped the schema name in my previous message,
“funky_development”, rather than “funk_development”.

Also, I’m using MySQL 5.0 on Windows XP, with Rails 1.1, Ruby 1.8.2, and
Rake 0.7.0.

Thanks,
Jeff C.man

Hello Jeff,

2006/4/5, Jeff C.man [email protected]:

001_item.rb:
class Item < ActiveRecord::Migration
end

002_item.rb
class Item < ActiveRecord::Migration
end

You must have different names for each migration. The second
migration overwrote the first one, which means the table didn’t get
created as your migration expected.

For you original problem, I think the problem might have been related
to the fact you typed version as “006” instead of plain “6”.

Try that and see how it goes.

Bye !

Each migration should have a unique name or you get a class name
conflict.

In your case Migrate has created two classes with the same name ‘Item’:

class Item < ActiveRecord::Migration

end

try it with itema and itemb.

Are all of your migration classes named the same?

This could be causing errors.

François Beausoleil wrote:

Hello Jeff,

2006/4/5, Jeff C.man [email protected]:

001_item.rb:
class Item < ActiveRecord::Migration
end

002_item.rb
class Item < ActiveRecord::Migration
end

You must have different names for each migration. The second
migration overwrote the first one, which means the table didn’t get
created as your migration expected.

For you original problem, I think the problem might have been related
to the fact you typed version as “006” instead of plain “6”.

Try that and see how it goes.

Bye !

Oh, I should name the migration something like:

001_item_tables.rb
002_item_names.rb
003_item_prices.rb

Like so?

I figured the number itself would control the versioning and the rest of
the filename should be the same.

Jeff

sean lynch wrote:

Each migration should have a unique name or you get a class name
conflict.

In your case Migrate has created two classes with the same name ‘Item’:

class Item < ActiveRecord::Migration

end

try it with itema and itemb.

Are all of your migration classes named the same?

This could be causing errors.

So far I’ve only used one migration per application. I tried that
example first with migrations called “001_funky.rb”/“002_funky.rb” and
then changed their names to “item” instead of “funky”.

Are you saying there should be a different migration for each table?

Jeff

Thans, guys. I hadn’t realized migrations should each be named
differently. I have to admit I don’t understand why that is. I was
assuming I could just create a sequence of migrations tied to my
application–for example, 001_blog.rb to 002_blog.rb for an app called
“blog”.

But at least now I understand how it does work. Thanks!
Jeff

that should be

  drop_table :new_table

I forgot to overwrite the code to my example names

def self.down
remove_column :old_table, :new_table_id_id
drop_table :orders <----error here
end

that should be

  remove_column :old_table, :new_table_id
  drop_table :new_table

I forgot to overwrite the code to my example names

def self.down
remove_column :old_table, :new_table_id <----error here
drop_table :orders <----error here
end

You can have multiple tables in a migration, but the migrations must
have unique names, because the class created in the migration is based
on the name you give.

The 001 or 002 from the file name is not included in the class name.

Here is an example that creates a new table and adds a column to an
existing table:

class Addtable2 < ActiveRecord::Migration

def self.up
create_table :new_table do |table|
table.column :name, :string
table.column :address, :text
table.column :pay_type, :string
end
add_column :old_table, :new_table_id, :integer
end

def self.down
remove_column :old_table, :new_table_id_id
drop_table :orders
end
end

The create table and the add column is at the same level. I could have
multiple create tables.

The new column in the old_table will hold the id from the new_table, so
I remove the column before dropping the table in my self.down


-sean
Jeff C.man wrote:

Thans, guys. I hadn’t realized migrations should each be named
differently. I have to admit I don’t understand why that is. I was
assuming I could just create a sequence of migrations tied to my
application–for example, 001_blog.rb to 002_blog.rb for an app called
“blog”.

But at least now I understand how it does work. Thanks!
Jeff

Look in the files created by your migrations with the same names. You
will see a class named after the name you give. having multiple classes
with the same name causes namespace collisions.

Just like in most other OO languages.

There is always that one joker on any java project who has to redefine
the ‘+’ operator to do subtraction. You know.

-Sean

Jeff C.man wrote:

Thans, guys. I hadn’t realized migrations should each be named
differently. I have to admit I don’t understand why that is. I was
assuming I could just create a sequence of migrations tied to my
application–for example, 001_blog.rb to 002_blog.rb for an app called
“blog”.

But at least now I understand how it does work. Thanks!
Jeff

“sean” == sean lynch [email protected] writes:

You can have multiple tables in a migration, but the migrations must
have unique names, because the class created in the migration is based
on the name you give.

The 001 or 002 from the file name is not included in the class name.

Perhaps it should be, just to prevent this kind of confusion. It’s not
the first time someone’s posted about exactly this problem on this
list, and the current behaviour is somewhat counterintuitive.

	     Calle D. <[email protected]>
	 http://www.livejournal.com/users/cdybedahl/

“You know, if I garbage collected my brain I wouldn’t have anything
left.”
– Paul Tomblin, BofhNet

Thanks, Sean.

I guess it just seemed natural to me that there’d be a global
application-level series of migrations, that would run in sequence.
It’s cleared up now, though. Thanks!

Jeff

sean lynch wrote:

Look in the files created by your migrations with the same names. You
will see a class named after the name you give. having multiple classes
with the same name causes namespace collisions.

Just like in most other OO languages.

There is always that one joker on any java project who has to redefine
the ‘+’ operator to do subtraction. You know.

-Sean

Jeff C.man wrote:

Thans, guys. I hadn’t realized migrations should each be named
differently. I have to admit I don’t understand why that is. I was
assuming I could just create a sequence of migrations tied to my
application–for example, 001_blog.rb to 002_blog.rb for an app called
“blog”.

But at least now I understand how it does work. Thanks!
Jeff

Calle D. wrote:

“sean” == sean lynch [email protected] writes:

You can have multiple tables in a migration, but the migrations must
have unique names, because the class created in the migration is based
on the name you give.

The 001 or 002 from the file name is not included in the class name.

Perhaps it should be, just to prevent this kind of confusion. It’s not
the first time someone’s posted about exactly this problem on this
list, and the current behaviour is somewhat counterintuitive.

       Calle D. <[email protected]>

Frankly I don’t quite understand why the behavior I thought was
intuitive doesn’t work? It seemed very natural to me to think that,
since the files are numbered in sequence, the text part of the filename
and class should be the same.

I see now that, I guess because of how it’s implemented, they’re classes
which have to be named differently so they don’t clash, but to have an
app called “blog” and a series of migrations called “001_blog”,
“002_blog”, “003_blog” seemed natural and intuitive to me.

Jeff C.man