rails:table已经存在于新的git分支上

时间:2012-03-02 05:03:27

标签: ruby-on-rails git

我正在尝试使用所有使用设计的不同消息传递宝石。因此,在git的master分支上安装Devise之后,我检查了一个新的分支来尝试一个gem“rails messaging”https://github.com/frodefi/rails-messaging,当我无法使它工作时,我将更改提交到该分支,然后我回到主人并检查了一个新的分支,尝试另一个宝石“邮箱”https://github.com/ging/mailboxer/tree/master/lib。在这个新分支的gemfile中没有来自第一个分支的gems的痕迹,但是当我在安装gem之后尝试rake db:migrate for this second branch时,我收到了这个错误消息,这似乎表明了一个表来自除非做了

,否则第一个分支干扰第二个分支的rake
 rails g mailboxer:install

它会自动运行rake db:migrate。但是,自述文件说我必须运行rake db:migrate,所以我不确定......

rake aborted!
An error has occurred, this and all later migrations canceled:

SQLite3::SQLException: table "conversations" already exists: CREATE TABLE "conversations" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "subject" varchar(255) DEFAULT '', "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL

有谁能建议我如何解决这个问题?我真的不知道要运行什么命令来解决这个问题。

这是scheme.rb文件。根据索引“消息传递用户”,我猜测它是由rails messaging gem(在第一个分支上)创建的设置,但我不完全确定。我查看了git上的源代码,但因为我不是很有经验而丢失了。

ActiveRecord::Schema.define(:version => 20120302041333) do

  create_table "conversations", :force => true do |t|
    t.string   "subject",    :default => ""
    t.datetime "created_at",                 :null => false
    t.datetime "updated_at",                 :null => false
  end

  create_table "messaging_users", :force => true do |t|
    t.string   "email",                                 :default => "", :null => false
    t.string   "encrypted_password",     :limit => 128, :default => "", :null => false
    t.string   "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.integer  "sign_in_count",                         :default => 0
    t.datetime "current_sign_in_at"
    t.datetime "last_sign_in_at"
    t.string   "current_sign_in_ip"
    t.string   "last_sign_in_ip"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  add_index "messaging_users", ["email"], :name => "index_messaging_users_on_email", :unique => true
  add_index "messaging_users", ["reset_password_token"], :name => "index_messaging_users_on_reset_password_token", :unique => true

  create_table "notifications", :force => true do |t|
    t.string   "type"
    t.text     "body"
    t.string   "subject",              :default => ""
    t.integer  "sender_id"
    t.string   "sender_type"
    t.integer  "conversation_id"
    t.boolean  "draft",                :default => false
    t.datetime "updated_at",                              :null => false
    t.datetime "created_at",                              :null => false
    t.integer  "notified_object_id"
    t.string   "notified_object_type"
    t.string   "notification_code"
  end

  add_index "notifications", ["conversation_id"], :name => "index_notifications_on_conversation_id"

  create_table "receipts", :force => true do |t|
    t.integer  "receiver_id"
    t.string   "receiver_type"
    t.integer  "notification_id",                                  :null => false
    t.boolean  "read",                          :default => false
    t.boolean  "trashed",                       :default => false
    t.boolean  "deleted",                       :default => false
    t.string   "mailbox_type",    :limit => 25
    t.datetime "created_at",                                       :null => false
    t.datetime "updated_at",                                       :null => false
  end

  add_index "receipts", ["notification_id"], :name => "index_receipts_on_notification_id"

  create_table "users", :force => true do |t|
    t.string   "email",                                 :default => "", :null => false
    t.string   "encrypted_password",     :limit => 128, :default => "", :null => false
    t.string   "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.integer  "sign_in_count",                         :default => 0
    t.datetime "current_sign_in_at"
    t.datetime "last_sign_in_at"
    t.string   "current_sign_in_ip"
    t.string   "last_sign_in_ip"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.string   "name"
  end

  add_index "users", ["email"], :name => "index_users_on_email", :unique => true
  add_index "users", ["reset_password_token"], :name => "index_users_on_reset_password_token", :unique => true

end

2 个答案:

答案 0 :(得分:2)

这里的问题是,虽然您的代码,模式,宝石和迁移都存储在git中,但数据库本身却不是。因此,当您在分支之间切换时,数据库仍保持其状态。

这些解决方案都可行:

  1. 删除并重新种子数据库

    rake db:reset
    
  2. 向下迁移(在旧分支上)以撤消迁移。我不确定gem是否在db / migrate中安装了迁移,或者是否直接从gem运行迁移,因此这并不容易,但如果您不想擦除数据,则更好的数据完整性。< / p>

  3. 重新加载你在git中存储的模式(这与第一个模式具有相同的效果)

    rake db:schema:load
    
  4. 现在使用sqlite数据库 - 虽然不适合生产,如果你将数据库签入git,它会表现为你希望当前数据库的行为。我应该警告你,尽管像这样的大文件会很痛苦。最好使用其他方法之一。

答案 1 :(得分:0)

是的,切换具有不同迁移级别的分支是一团糟。没有'单线'可以做到这一点。有四件事可能不同步。你需要:

1)确定您的分支有哪些迁移:

(look at the contents of db/migrations)

2)确定您的应用对数据库的看法:

(look at db/schema.rb)

3)通过查看schema_migrations表来确定您的数据库认为它具有哪些迁移:

~> rails db console

(opens up your db console, in my case mysql...)

mysql> SELECT * FROM schema_migrations; # don't forget the ';' at the end!

(outputs big huge list of migration timestamps)

4)查看实际表格,了解是否已应用迁移。

mysql> describe table_name;

(outputs the column names, see if they have been updated per the migration)

5)现在需要思考的部分。有几种可能的情况。我只能跟我遇到的那个说话:

  • 您的迁移文件(1),schema.rb(2)和实际表(4)匹配,但您的schema_migrations表(3)缺少迁移时间戳。这是我的问题。
    • 如果您不关心数据:rake db:reset。它将废弃整个数据库并从头开始重新构建结构
  • 请使用解决方案建议其他方案..