我已经在本地工作了一段时间的rails应用程序,并且大部分应用程序都保留在localhost中。我已经对Heroku进行了一次部署测试,并且从那以后开发了更多的应用程序。那么现在我想把更新的版本推到heroku但是我遇到了最糟糕的时间。首先,我已经生活并了解了一致数据库的重要性(test / dev使用sqlite3,heroku使用postgres)。
我已经将测试/开发数据库从sqlite3移动到了postgres工作正常,但是当我推送到heroku时我仍然遇到问题,即使我使用的是postgres,我还没有在本地工作。
以下是我遇到的错误:
== 20150713172604 ChangingRoomTimeToDatetime: migrating =======================
-- change_column(:rooms, :start_time, :timestamptz)
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:
PG::DatatypeMismatch: ERROR: column "start_time" cannot be cast automatically to type timestamp with time zone
HINT: Specify a USING expression to perform the conversion.
: ALTER TABLE "rooms" ALTER COLUMN "start_time" TYPE timestamptz/app/vendor/bundle/ruby/2.0.0/gems/activerecord-4.1.8/lib/active_record/connection_adapters/postgresql/database_statements.rb:128:in `async_exec'
最初我使用时间数据类型的房间,直到我意识到日期也很重要:
class AddingTimeToRoomModel < ActiveRecord::Migration
def change
add_column :rooms, :start_time, :time
add_column :rooms, :end_time, :time
end
end
变化:
class ChangingRoomTimeToDatetime < ActiveRecord::Migration
def change
change_column :rooms, :start_time, :timestamptz
change_column :rooms, :end_time, :timestamptz
end
end
此时数据并不重要,因为数据库中的唯一数据是我无意中删除/删除的测试数据。我曾经尝试过使用:timestamp和:timestamptz,但我无法得到任何工作,我很困惑为什么它在本地运行但不在heroku上运行。
答案 0 :(得分:1)
问题是timestampz
的信息多于time
。来自fine manual:
timestamp with time zone
日期和时间,时区
[...]
time
一天中的时间(没有日期)
您可以使用USING clause将列类型转换为timestampz
时为您的时间添加日期:
可选的
USING
子句指定如何从旧的计算新列值;如果省略,则默认转换与从旧数据类型转换为new的赋值相同。如果没有从旧类型到新类型的隐式或赋值转换,则必须提供USING
子句。
但是,您的评论表明您并不关心您拥有的数据,因此我只需通过一次迁移删除现有列,然后使用其他迁移重新添加该列:
class RemoveTimeFromRoomModel < ActiveRecord::Migration
def change
remove_column :rooms, :start_time
remove_column :rooms, :end_time
end
end
class ReAddTimeToRoomModel < ActiveRecord::Migration
def change
add_column :rooms, :start_time, :timestampz
add_column :rooms, :end_time, :timestampz
end
end
我不确定SQLite会对:timestampz
做什么,但它最终可能会以text
结尾。 OTOH,在一个数据库上开发并在另一个数据库上部署是一个痛苦和痛苦的捷径,所以我建议你将开发环境切换到PostgreSQL,这样你就不用担心了。
答案 1 :(得分:1)
您可以使用明确的USING
表达式和类型转换来执行此操作:
change_column :rooms, :start_time, 'timestamptz using start_time::timestamptz'