Rails Postgres数据类型不匹配 - “无法自动转换为输入日期”

时间:2016-08-31 22:52:32

标签: ruby-on-rails postgresql ruby-on-rails-4 heroku rails-activerecord

我从sqlite迁移到Postgres所以我可以推送到Heroku,并在运行$ heroku run rake db:migrate:

时收到错误
 ActiveRecord::SchemaMigration Load (0.9ms)  SELECT "schema_migrations".* FROM     "schema_migrations"
Migrating to ChangeCheckIn (20160726015859)
(0.7ms)  BEGIN
== 20160726015859 ChangeCheckIn: migrating      ====================================
-- change_column(:listings, :check_in_date, :date)
 (1.3ms)  ALTER TABLE "listings" ALTER COLUMN "check_in_date" TYPE date
(0.7ms)  ROLLBACK
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:

PG::DatatypeMismatch: ERROR:  column "check_in_date" cannot be cast automatically to type date
HINT:  You might need to specify "USING check_in_date::date".
: ALTER TABLE "listings" ALTER COLUMN "check_in_date" TYPE date

当我最初构建模型:listing时,check_in_date是type:date,但是我通过迁移到字符串来改变它,在模式中它当前是一个字符串。下面的错误是在我将其更改为字符串之前引用初始迁移和旧数据类型。

然后我在SO上针对此问题创建了一个新的迁移(下面),并收到了一个新错误(如下所示):Rails migrations - change_column with type conversion

change_column :listings, :check_in_date, 'string USING CAST(check_in_date AS string)' 

PG::UndefinedObject: ERROR:  type "string" does not exist

我在这里做错了什么?

1 个答案:

答案 0 :(得分:0)

PostgreSQL中没有string类型,您需要textvarchar。 SQLite允许您逃避这一点,因为它将任何无法识别的类型视为text的别名。但是,迁移中有t.string方法,但会创建varchar列,因此您可能只会遇到一些术语混淆。

你想要更像这样的东西:

change_column :listings, :check_in_date, 'text using cast(check_in_date as text)'

或使用PostgreSQL特定的转换:

change_column :listings, :check_in_date, 'text using check_in_date::text'

请注意,迁移中的t.string会在数据库中创建varchar(255)列,而varchar(n)text内部相同({{1}除外) 1}})在PostgreSQL中,所以除非你特别需要数据库中的长度限制,否则你通常会使用varchar(n)