21

There is a good question here I want to elaborate on. I am trying to convert a column in my database form a string to an integer.

I thought the conversion would be pretty straight forwrad. Currently my strings are

["10", "12", "125", "135", "140", ...]

My migration file includes:

def change
    change_column :table_name, :product_code, :integer
end

Rails tries this but Postgresql thows back an error.

PG::Error: ERROR: column "product_code" cannot be cast automatically to type integer
HINT: Specify a USING expression to perform the conversion.

I am not sure how I use this 'USING' expression in my rails migration.

So I thought the conversion would be pretty straight forward. What should I use as the USING expression?

Community
  • 1
  • 1
Jay Killeen
  • 2,832
  • 6
  • 39
  • 66
  • 1
    Thanks for asking this question. Keep it up – boulder_ruby Jun 11 '14 at 23:32
  • I have been reading a book about SQL and now am shaking my head. Ofcourse you can't just convert strings to integers without using some SQL statements to say how you want to CAST it. Wish I knew all about SQL a long time ago. – Jay Killeen Oct 18 '15 at 02:11

3 Answers3

31
change_column :table_name, :product_code,
  'integer USING CAST(product_code AS integer)'

Source: http://makandracards.com/makandra/18691-postgresql-vs-rails-migration-how-to-change-columns-from-string-to-integer

Björn Nilsson
  • 3,703
  • 1
  • 24
  • 29
19

Adjusted code to support converting blank strings, too:

change_column :table_name, :product_code, 
  "integer USING NULLIF(product_code, '')::int"

Empty string becomes NULL, which becomes 0 on type conversion, which is probably the best you can do in this situation.

florish
  • 557
  • 5
  • 10
  • 1
    Works like a charm. I had the same issue - the migration from http://stackoverflow.com/a/22394425/1513205 works great on an empty database - but our database already have empty string values in it. – watts Feb 11 '16 at 18:17
0

When you write Rails migrations to convert a string column to an integer you'd usually write like this:

change_column :table_name, :column_name, :integer

You might get this:

PG::DatatypeMismatch: ERROR:  column "column_name" cannot be cast automatically to type integer
HINT:  Specify a USING expression to perform the conversion.

The "hint" basically tells you that you need to confirm you want this to happen, and how data shall be converted. Just say this in your migration:

change_column :table_name, :column_name, 'integer USING CAST(column_name AS integer)'
Subhash Chandra
  • 3,165
  • 1
  • 27
  • 30