Heroku run rails db:migrate showing PG::DuplicateColumn: ERROR: column "created_at" of relation "blogs" already exists

Heroku run rails db:migrate showing PG::DuplicateColumn: ERROR: column "created_at" of relation "blogs" already exists

当我尝试 运行 heroku 运行 rails db:migrate 时,出现以下错误

Running rails db:migrate on ⬢ sharley... up, run.6479 (Free)
I, [2021-01-03T23:13:45.240708 #4]  INFO -- : Migrating to AddTimestampToBlogs (20201225171213)
== 20201225171213 AddTimestampToBlogs: migrating ==============================
-- add_timestamps(:blogs, {:null=>true})
rails aborted!
StandardError: An error has occurred, this and all later migrations canceled:

PG::DuplicateColumn: ERROR:  column "created_at" of relation "blogs" already exists
/app/vendor/bundle/ruby/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/postgresql/database_statements.rb:47:in `exec'
/app/bin/rails:4:in `<main>'

Caused by:
PG::DuplicateColumn: ERROR:  column "created_at" of relation "blogs" already exists
/app/vendor/bundle/ruby/2.7.0/gems/activerecord-6.1.0/lib/active_record/connection_adapters/postgresql/database_statements.rb:47:in `exec'
/app/bin/rails:4:in `<main>'
Tasks: TOP => db:migrate
(See full trace by running task with --trace)

这是我的架构文件 请,任何帮助将不胜感激。找遍了也没用。

ActiveRecord::Schema.define(version: 2020_12_29_225613) do

  create_table "blogs", force: :cascade do |t|
    t.string "name"
    t.string "title"
    t.string "content"
    t.datetime "created_at", precenter code hereision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.integer "user_id"
    t.index ["user_id"], name: "index_blogs_on_user_id"
  end

  create_table "comments", force: :cascade do |t|
    t.string "name"
    t.text "body"
    t.integer "blog_id", null: false
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.integer "post_id"
    t.integer "user_id"
    t.index ["blog_id"], name: "index_comments_on_blog_id"
  end

  create_table "users", force: :cascade do |t|
    t.string "email", default: "", null: false
    t.string "encrypted_password", default: "", null: false
    t.string "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.string "name"
    t.integer "user_id"
    t.index ["email"], name: "index_users_on_email", unique: true
    t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
  end

  add_foreign_key "comments", "blogs"
end

这是我在博客文件中添加的时间戳

class AddTimestampsToBlogs < ActiveRecord::Migration[6.1]
    def change
        add_timestamps :blogs, null: true
        # backfill existing record with created_at and updated_at
        # values making clear that the records are faked
        long_ago = DateTime.new(2020, 12, 29)
        Blog.update_all(created_at: long_ago, updated_at: long_ago)
        # change not null constraints
        change_column_null :blogs, :created_at, false
        change_column_null :blogs, :updated_at, false
    end
end

还有什么需要的吗?

您可以添加 add_timestamps(:blogs, {:null=>true}) unless column_exists?(:blogs, :created_at) && column_exists?(:blogs, :updated_at)。看起来有人部署了一个迁移来修复这个问题,现在你也在尝试。如果有条件,它只会 运行 add_timestamps 迁移方法,如果在列

没有创建或更新

更新

在迁移中添加条件。使用条件,如果时间戳列不存在,它只会 运行 该步骤。问题是您或您团队中的某个人在 heroku 上进行了 运行 迁移,然后可能在本地回滚然后重新部署。数据库仍然有那个变化,因此你收到的错误。因此,如果您添加条件,它只会在 table

上不存在时间戳列时才添加它们
def change
        add_timestamps :blogs, null: true unless column_exists??(:blogs, :created_at) && column_exists?(:blogs, :updated_at)
        # backfill existing record with created_at and updated_at
        # values making clear that the records are faked
        long_ago = DateTime.new(2020, 12, 29)
        Blog.update_all(created_at: long_ago, updated_at: long_ago)
        # change not null constraints
        change_column_null :blogs, :created_at, false
        change_column_null :blogs, :updated_at, false
    end