无法迁移到 heroku(Ruby Rails 教程 [Michael Hartl] 第 10 章)
Can't migrate to heroku (Ruby on Rails tutorial [Michael Hartl] chaper 10)
我正在阅读 Hartl 书的第 10 章。在本章的最后,我们重置了 heroku 数据库,然后进行了迁移。但是当我 运行:
heroku run rails db:migrate
我收到一个错误:
rails aborted!
StandardError: An error has occurred, this and all later migrations canceled:
PG::UndefinedColumn: ERROR: column "password_digest_string" of relation "users" does not exist
: ALTER TABLE "users" DROP "password_digest_string"
在本教程的前面部分,我删除了一个名为 password_digest_string 的列,因为它的命名不正确而且我还不需要它。似乎 rails 正在尝试再次删除该列,即使它不再存在。我删除了删除此列的迁移文件,但它仍在尝试删除它。同样奇怪的是,自删除该列以来,我已经多次迁移数据库,并且在我重置它之前从未遇到过这个问题。有什么建议吗?
编辑:
这是我的架构文件:
ActiveRecord::Schema.define(version: 20170121224748) do
create_table "users", force: :cascade do |t|
t.string "name"
t.string "email"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "password_digest"
t.string "remember_digest"
t.boolean "admin", default: false
t.index ["email"], name: "index_users_on_email", unique: true
end
end
编辑:
我的迁移是按时间戳顺序进行的。
..._create_users.rb
class CreateUsers < ActiveRecord::Migration[5.0]
def change
create_table :users do |t|
t.string :name
t.string :email
t.timestamps
end
end
end
..._add_index_to_users_email.rb
class AddIndexToUsersEmail < ActiveRecord::Migration[5.0]
def change
add_index :users, :email, unique: true
end
end
..._add_password_digest_to_users.rb
class AddPasswordDigestToUsers < ActiveRecord::Migration[5.0]
def change
add_column :users, :password_digest, :string
end
end
..._remove_columns.rb
class RemoveColumns < ActiveRecord::Migration[5.0]
def self.up
remove_column :users, :password_digest_string
end
end
..._add_remember_digest_to_users.rb
class AddRememberDigestToUsers < ActiveRecord::Migration[5.0]
def change
add_column :users, :remember_digest, :string
end
end
..._add_admin_to_users.rb
class AddAdminToUsers < ActiveRecord::Migration[5.0]
def change
add_column :users, :admin, :boolean, default: false
end
end
$> heroku pg:reset DATABASE
将使 heroku 上的 db:migrate 再次干净
在我看来,AddPasswordDigestToUsers
迁移最初看起来像这样(可能是您拼错了):
class AddPasswordDigestToUsers < ActiveRecord::Migration[5.0]
def change
add_column :users, :password_digest_string
end
end
然后您意识到该列应该只是 password_digest
。因此,您手动将迁移文件编辑为现在的样子,回滚,创建下一个迁移,即 RemoveColumns
,然后是 运行 迁移。
现在,当您从头开始迁移时,由于 the way column removal is handled in sqlite,如果您使用 sqlite3
(这是您用于开发环境的),将不会出现错误。但是使用Postgres会报错
你应该做的
您应该创建一个迁移来更改列名,而不是您所做的,就像这样:
class RenamePasswordDigestStringColumn < ActiveRecord::Migration[5.0]
def self.up
rename_column :users, :password_digest_string, :password_string
end
end
你现在可以做什么
要在不做太多更改的情况下解决问题,您可以删除 RemoveColumns
迁移(并提交、推送...等等)。那没关系,我认为它不会损害您的生产或开发环境。
我正在阅读 Hartl 书的第 10 章。在本章的最后,我们重置了 heroku 数据库,然后进行了迁移。但是当我 运行:
heroku run rails db:migrate
我收到一个错误:
rails aborted!
StandardError: An error has occurred, this and all later migrations canceled:
PG::UndefinedColumn: ERROR: column "password_digest_string" of relation "users" does not exist
: ALTER TABLE "users" DROP "password_digest_string"
在本教程的前面部分,我删除了一个名为 password_digest_string 的列,因为它的命名不正确而且我还不需要它。似乎 rails 正在尝试再次删除该列,即使它不再存在。我删除了删除此列的迁移文件,但它仍在尝试删除它。同样奇怪的是,自删除该列以来,我已经多次迁移数据库,并且在我重置它之前从未遇到过这个问题。有什么建议吗?
编辑:
这是我的架构文件:
ActiveRecord::Schema.define(version: 20170121224748) do
create_table "users", force: :cascade do |t|
t.string "name"
t.string "email"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "password_digest"
t.string "remember_digest"
t.boolean "admin", default: false
t.index ["email"], name: "index_users_on_email", unique: true
end
end
编辑:
我的迁移是按时间戳顺序进行的。
..._create_users.rb
class CreateUsers < ActiveRecord::Migration[5.0]
def change
create_table :users do |t|
t.string :name
t.string :email
t.timestamps
end
end
end
..._add_index_to_users_email.rb
class AddIndexToUsersEmail < ActiveRecord::Migration[5.0]
def change
add_index :users, :email, unique: true
end
end
..._add_password_digest_to_users.rb
class AddPasswordDigestToUsers < ActiveRecord::Migration[5.0]
def change
add_column :users, :password_digest, :string
end
end
..._remove_columns.rb
class RemoveColumns < ActiveRecord::Migration[5.0]
def self.up
remove_column :users, :password_digest_string
end
end
..._add_remember_digest_to_users.rb
class AddRememberDigestToUsers < ActiveRecord::Migration[5.0]
def change
add_column :users, :remember_digest, :string
end
end
..._add_admin_to_users.rb
class AddAdminToUsers < ActiveRecord::Migration[5.0]
def change
add_column :users, :admin, :boolean, default: false
end
end
$> heroku pg:reset DATABASE
将使 heroku 上的 db:migrate 再次干净
在我看来,AddPasswordDigestToUsers
迁移最初看起来像这样(可能是您拼错了):
class AddPasswordDigestToUsers < ActiveRecord::Migration[5.0]
def change
add_column :users, :password_digest_string
end
end
然后您意识到该列应该只是 password_digest
。因此,您手动将迁移文件编辑为现在的样子,回滚,创建下一个迁移,即 RemoveColumns
,然后是 运行 迁移。
现在,当您从头开始迁移时,由于 the way column removal is handled in sqlite,如果您使用 sqlite3
(这是您用于开发环境的),将不会出现错误。但是使用Postgres会报错
你应该做的
您应该创建一个迁移来更改列名,而不是您所做的,就像这样:
class RenamePasswordDigestStringColumn < ActiveRecord::Migration[5.0]
def self.up
rename_column :users, :password_digest_string, :password_string
end
end
你现在可以做什么
要在不做太多更改的情况下解决问题,您可以删除 RemoveColumns
迁移(并提交、推送...等等)。那没关系,我认为它不会损害您的生产或开发环境。