I have a currency(ccy) column on my event model and it's currently a string, I'd like to change it to a integer.
Although it works on my local environment, the following error was displayed when I try heroku run rake db:migrate to heroku.
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:
PG::InvalidTextRepresentation: ERROR: invalid input syntax for integer: ""
: ALTER TABLE "events" ALTER COLUMN "ccy" TYPE integer USING CAST(ccy AS integer)
The migration file as below.
class ChangeCcyToEvents < ActiveRecord::Migration
def change
change_column :events, :ccy, 'integer USING CAST(ccy AS integer)'
end
end
I found the similar question PG::InvalidTextRepresentation: ERROR: invalid input syntax for integer: "M", so I changed migration file as below. But the result is the same.
class ChangeCcyToEvents < ActiveRecord::Migration
def change
Event.where(ccy: '').update_all(ccy: '')
change_column :events, :ccy, 'integer USING CAST(ccy AS integer)'
end
end
There is no value in all ccy column so far.
It would be appreciated if you could give me any advice.
Your migration is trying to convert a "" into an integer, which postgres complais about it (and it should, because it's not a valid conversion).
You should update your content for invalid cases before changing the column type:
class ChangeCcyToEvents < ActiveRecord::Migration
def up
Event.where("ccy IS NULL OR ccy = ''").update_all({ccy: '0'})
change_column :events, :ccy, 'integer USING CAST(ccy AS integer)'
end
def down
raise ActiveRecord::IrreversibleMigration
end
end
Perhaps is not complaining in development (localhost) because you're using a different version of postgreSQL than Heroku.
Next time, try using default values in migrations for this kind of columns.
Related
I am upgrading my rails 3 application to rails 4. And according to the guide I removed this line from my model
serialize :my_serialized_column, ActiveRecord::Coders::Hstore.new({})
but now I am getting the error while looping over :my_serialized_column which was previously hash
undefined method `each' for "":String
Now my question is how do I change the data_type of my column without losing the data I already have
So you can just change the data type of the column from string to hstore.
One thing to keep in mind is you need to cast the data to hstore or you will get the following error
PG::DatatypeMismatch: ERROR: column "my_serialized_column" cannot be cast automatically to type hstore
HINT: You might need to specify "USING my_serialized_column::hstore".
To avoid the error you can specify the casting
class ChangeMySerializedColumnTypeToHstore < ActiveRecord::Migration
def up
change_column_null :my_table, :my_serialized_column, ''
change_column :my_table, :my_serialized_column, "hstore USING my_serialized_column::hstore"
end
def down
change_column :my_table, :my_serialized_column, :string, default: ''
end
end
I generated a bad migration and the file looked like this
class AddActivexToMat < ActiveRecord::Migration
def change
add_column :mats, :is_active, :boolean
add_column :mats, :default, :true
end
end
Without checking the migration file, I ran rake db:migrate and now my schema reads
# Could not dump table "mats" because of following NoMethodError
#undefined method `[]' for nil:NilClass
I tried to remove columns but getting the following errors
StandardError: An error has occurred, this and all later migrations canceled:
undefined method to_sym' for nil:NilClass/Users/jhorsch/.rvm/gems/ruby-2.0.0-p247#global/gems/activerecord-4.0.2/lib/active_record/connection_adapters/abstract/schema_definitions.rb:215:incolumn'
I don't think changing the columns will work either and I am afraid to drop the table. I don't think I can just drop a table and add a new one with the same table name. In this case the table name was 'Mats'
Luckily this table only had one previous column 'name'
Any ideas how to fix this?
Seems like you specify incorrect column type here:
add_column :mats, :default, :true
:true is invalid column type.
I was moving my app from Nitrous.io which uses SQLite to Heroku for production which uses Postgres, and I got the following error. 2 things, I don't get why it won't do change_column, and I definitely don't understand their "hint". How can I go about implementing properly?
-- change_column(:messages, :sender, :integer)
PG::DatatypeMismatch: ERROR: column "sender" cannot be cast automatically to type integer
HINT: Specify a USING expression to perform the conversion.
: ALTER TABLE "messages" ALTER COLUMN "sender" TYPE integer
The attributes were strings, and I wanted to change to integers so I could reference them.
Any help?
Below is my db migration that it is referencing:
class ChangeSenderReceiverToInteger < ActiveRecord::Migration
def change
change_column(:messages, :sender, :integer)
change_column(:messages, :receiver, :integer)
end
end
Try:
change_column(:messages, :sender, 'integer USING CAST(sender AS integer)')
Ref: http://makandracards.com/makandra/18691-postgresql-vs-rails-migration-how-to-change-columns-from-string-to-integer
I'm new to ruby on rails, github and heroku. Now i am doing fixed deposit project in that project i am using database sqlite3 in my localhost and postgres in heroku.
I have add a field called int which datatype is string and i changed the datatype from string to integer. Finally, i decided to change it again from integer to float.
In my local host its working perfecly. But, when i'm trying to run in heroku it shows rake aborted.
heroku run rake db:migrate
it shows the following error message
Running `rake db:migrate` attached to terminal... up, run.4356
Connecting to database specified by DATABASE_URL
Migrating to CreateFds (20140505120047)
Migrating to Changedatatypeforfd (20140506065307)
Migrating to AddMdToFds (20140506080333)
Migrating to AddIntToFds (20140506080404)
Migrating to Changedatatypeforint (20140506103001)
== Changedatatypeforint: migrating ======================
-- change_column(:fds, :int, :integer)
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:
PGError: ERROR: column "int" cannot be cast automatically to type integer
HINT: Specify a USING expression to perform the conversion.
: ALTER TABLE "fds" ALTER COLUMN "int" TYPE integer
my db files are listed below
20140506080404_add_int_to_fds.rb
class AddIntToFds < ActiveRecord::Migration
def change
add_column :fds, :int, :string
end
end
20140506103001_changedatatypeforint.rb
class Changedatatypeforint < ActiveRecord::Migration
def up
change_column :fds, :int, :integer
end
def down
change_column :fds, :int, :string
end
end
20140508105541_rechangedatatypeforint.rb
class Rechangedatatypeforint < ActiveRecord::Migration
def up
change_column :fds, :int, :float
end
def down
change_column :fds, :int, :integer
end
end
Sorry for my blunder.
Please give me the solution.
Thanks in advance.
Heroku uses PostgreSQL. In PostgreSQL int is a reserved word, you cannot use it as a column name.
Use something else for your int name
change_column :fds, :valid_name, :integer
SQL Key Words
If you want to cast from float to integer, one way to do it is:
class MigrationNameHere < ActiveRecord::Migration
def up
execute('ALTER TABLE fds ALTER COLUMN column_name TYPE integer USING round(column_name);')
end
end
This migration will convert all your float numbers to integer ones and it is not reversible so be careful. I advise you to have a backup before doing this.
everyone. I'm trying to run a migration for my database (postgre) on Heroku, and when I run it, I get the following error:
PGError: ERROR: column "morning_meds" cannot be cast to type "pg_catalog.bool"
: ALTER TABLE "users" ALTER COLUMN "morning_meds" TYPE boolean
The migration file in question has the following code:
class ChangeUserMedsFieldsToBoolean < ActiveRecord::Migration
def down
change_column :users, :morning_meds, :string
change_column :users, :lunch_meds, :string
change_column :users, :night_meds, :string
end
def up
change_column :users, :morning_meds, :boolean
change_column :users, :lunch_meds, :boolean
change_column :users, :night_meds, :boolean
end
end
I'm not sure how to fix the error or what could be causing the error, so any help you could give me would be great!
It appears that Rails doesn't offer support for specifying a cast or transform function, which PostgreSQL requires for datatype changes where no implicit cast for that type pair exists.
You need to get Rails to execute:
ALTER TABLE users ALTER COLUMN col_name SET DATA TYPE morning_meds USING bool(col_name)
and since Rails apparently doesn't let you specify the USING clause via migrations, you need to do it manually. See this excellent answer.
Alternately you could, pre-migration, run:
CREATE FUNCTION bool(text) RETURNS BOOLEAN AS $$
SELECT bool($1);
$$ LANGUAGE 'sql';
CREATE CAST (text AS boolean) WITH FUNCTION bool(text) AS IMPLICIT;
which will allow the ALTER to proceed without an explicit USING clause. You can and probably should drop the cast and bool(text) function after the migration:
DROP CAST (text AS boolean);
DROP FUNCTION bool(text);