why is migration failing?

I have the following migration to add a new column

class AddLocationToTicket < ActiveRecord::Migration    def self.up      add_column :tickets, :location, :string, :null => false, :limit => 30    end

   def self.down      remove_column :tickets, :location    end end

I get the following when I run rake db:migrate, which doesn't make sense because nowhere am i specifing a default value!

== AddLocationToTicket: migrating

You're kidding right? That doesn't make sense?!

You're adding a column with no default value (so, that's a default value of "NULL") to a table which presumably already has data in it. And you're saying that the column should *not* allow NULL, even though you don't specify a default value. So the existing columns will all have NULL as the value for the field you just created, except you tell the DB that NULL is not allowed - so there's an exception.

Seems to make sense to me.

Either: delete all the existing data (assuming it's test/development data) before running the migration or specify a default value for the field...

I don't have any existing data. I do

rake db:migrate VERSION=0 rake db:migrate

What do you mean? how is that any different from the following which works fine!

class CreateTickets < ActiveRecord::Migration    def self.up      create_table :tickets do |t|        t.string :location, :null => false, :limit => 30

       t.timestamps      end    end

   def self.down      drop_table :tickets    end end

I don't have any existing data. I do

rake db:migrate VERSION=0 rake db:migrate

What do you mean? how is that any different from the following which works fine!

As ever, more information about the problem makes it more interesting.

Are you *sure* none of the other migrations create rows in the tickets table?

What if, for the curiosity of it, you alter the CreateTickets migration thus:

def self.up create_table :tickets do |t| # all your other columns here...

 t\.timestamps

end

   add_column :tickets, :location, :string, :null => false, :limit => 30 end

Does that work? (there's definitely no rows...) or does it fail with the same exception?

class CreateTickets < ActiveRecord::Migration def self.up create_table :tickets do |t| t.string :location, :null => false, :limit => 30

   t\.timestamps
 end

end

Well sqlite might consider creating a table to be different to adding a column to an existing table. The Sqlite3 docs for alter table do specifically say that you must provide a non null default when adding a non null column (while you are not setting a default, the default default is null)

Fred

While you're not specifying a default value, the default default value is NULL

Fred

I tried your suggestion, I get the same error. As Fred stated about sqlite3, you can't add a new field without specifying a default value for a non-null field. I was under the impression if the table was empty with no rows you should be able to do this.

It kind of sucks, because rather than using migration, I have to go back to my previous migration and just add the new field into the model so it works the way I want it without having to specify a non null value.

Since I am the only one working on this "sample" app, it's not a big deal and all source is under GIT control, so not a big deal. still I wanted to get into the habit of using migration.

I tried your suggestion, I get the same error. As Fred stated about sqlite3, you can't add a new field without specifying a default value for a non-null field. I was under the impression if the table was empty with no rows you should be able to do this.

Nice gotcha.... maybe it would be better for you to change from SQLite to something else? MySQL? PostgreSQL? Seeing as you're not going to deploy to SQLite, I've never understood the point of developing in it :-/

Since I am the only one working on this "sample" app, it's not a big deal and all source is under GIT control, so not a big deal. still I wanted to get into the habit of using migration.

It's a good habit; and if you can help it, you really *don't* want to get into the bad habit of editing migrations that have already been run (even if you are the only developer).

I guess out of laziness as I ramp-up my Rails skills I've stuck to using sqlite3, but I'll take your advice and give PostgreSQL a go. I agree it's better to develop good habits and stick with them. Also I have to get use to working with a production DB.

Doing a mental erase of my last comment about me falling back to editing old migrations by hand =P

My advice to you is to use mysql instead of sqlite and see the results as it is a sample app. If not, try to be a little through about sqlite before using. moreover mysql and postgre are widely used DBs and will help you in future.