11

I've been trying unsuccessfully to change a column type in my Postgres database from text to json. Here's what I've tried...

class ChangeNotesTypeInPlaces < ActiveRecord::Migration[5.0]
  def up
    execute 'ALTER TABLE places ALTER COLUMN notes TYPE json USING (notes::json)'
  end

  def down
    execute 'ALTER TABLE places ALTER COLUMN notes TYPE text USING (notes::text)'
  end
end

Also...

class ChangeNotesTypeInPlaces < ActiveRecord::Migration[5.0]
  def up
    change_column :places, :notes, 'json USING CAST(notes AS json)'
  end

  def down
    change_column :places, :notes, 'text USING CAST(notes AS text)'
  end
end

Both of these return the same error...

PG::InvalidTextRepresentation: ERROR:  invalid input syntax for type json
3
  • Are the notes column already had a value that is not a valid json? Commented Oct 30, 2016 at 2:07
  • That's a good question. I've never saved data in this column (in development, not the same case in production unfortunately), but I also don't have a not-null constraint on that column. Could it be that it has been saving an empty string into that column which is causing this? If yes, do you know how I can get around this? Commented Oct 30, 2016 at 2:18
  • 1
    If you don't have the not-null constraint, then null value would be just fine or you could just save empty json {}. It is not accepting empty string. Commented Oct 30, 2016 at 2:25

3 Answers 3

13

Using Rails 5.1.x and PostgreSQL 9.4, here is what worked for me when converting text columns (containing valid json) to jsonb columns :

class ChangeTextColumnsToJson < ActiveRecord::Migration[5.1]
  def change
    change_column :table_name, :column_name, :jsonb, using: 'column_name::text::jsonb'
  end
end
Sign up to request clarification or add additional context in comments.

2 Comments

This worked in postgres 9.6 rails 5.1, i had to add the reverse: def down change_column :table_name, :column_name, :text end
this same solution works for AR::Migration[6.1], as always, make sure the data is valid, otherwise advise add column, copy data rename column
3

I was able to accomplish it using:

def change
  change_column :places, :notes, :json, using: 'notes::JSON'
end

This won't be reversible though; I imagine you can split it out into separate up and down definitions, but I didn't feel the need to.

1 Comment

Should separate up and down.
0

I just solved a similar problem. Trying to adapt it for your question, it would look (mostly?) like this.

class ChangeNotesTypeInPlaces < ActiveRecord::Migration[5.0]
  def up
    change_column :places, :notes, :jsonb, using: 'CAST(value AS JSON)'
  end

  def down
    change_column :places, :notes, :text
  end
end

1 Comment

works for me if the word 'value' in the CAST is replaced with 'notes'

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.