29

Based on what I've found, I'm using this right now, but it's not working...

def change
 change_column :users, :twitter_id, :integer, :limit => 8
end
1
  • 1
    Still, if someone has an answer for how to do this with a change, I will mark it as the correct answer. Doing what I did solved the problem, but isn't really an answer to the question as it won't help anyone who comes across this problem later in the game when they can't just drop a table from their database Commented Oct 22, 2015 at 10:59

2 Answers 2

55

I just ran into the same issue. The following worked for me:

def up 
  change_column :my_table, :my_column, :bigint
end
Sign up to request clarification or add additional context in comments.

8 Comments

Does this just change the schema, or will every row in the table be updated? I.e. will it lock my table?
Doing this did not lock my table. In all honestly, I didn't check to see whether every row was changed or whether it was just the schema that was changed. It worked seamlessly, so I had no need to dig into further.
It definitely does lock the table. I'm pretty sure it's changing every row also. I added a couple dozen million records before a test migration, and I was not able to insert into the table during the migration which took hours. For anyone looking for zero downtime, I found this answer: stackoverflow.com/questions/33504982/…
Can you please help me same for the small integer?
I'd say this depends on your database. Postgress copies every row, and locks the table. In one scenario, I saw PG process about 1GB of table size/minute...but YMMV.
|
9

For anybody looking for different data types than :bigint, you can use :tinyint, :smallint and :mediumint as well, according to ActiveRecord type of integer (tinyint, smallint, mediumint, int, bigint)

# activerecord-3.0.0/lib/active_record/connection_adapters/mysql_adapter.rb
# Maps logical Rails types to MySQL-specific data types.
def type_to_sql(type, limit = nil, precision = nil, scale = nil)
  return super unless type.to_s == 'integer'

  case limit
  when 1; 'tinyint'
  when 2; 'smallint'
  when 3; 'mediumint'
  when nil, 4, 11; 'int(11)'  # compatibility with MySQL default
  when 5..8; 'bigint'
  else raise(ActiveRecordError, "No integer type has byte size #{limit}")
  end
end

Also, do use up and down for rails db:rollback; this is what worked for me:

class ChangeCarNumberOfKeysToSmallInt < ActiveRecord::Migration[5.2]
  def up
    change_column :cars, :number_of_keys, :tinyint
  end

  def down
    change_column :cars, :number_of_keys, :int
  end
end

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.