代码之家  ›  专栏  ›  技术社区  ›  Henry Yang

如果在“rake db:schema:load”之后立即运行“rake db:migrate”,为什么schema.rb会被修改?

  •  0
  • Henry Yang  · 技术社区  · 6 年前

    问题摘要:

    我克隆了一个名为DMP Roadmap的开源项目,并遵循其安装指南直到 rake db:schema:load

    那我会的 rake db:migrate rake db:迁移 不生成任何输出,这意味着不会更改任何内容,但架构文件已更改。

    下面一定有什么事情,有谁知道数据库迁移的来龙去脉,请解释一下下面发生了什么?

    复制步骤:

    在Mac OS上,brew安装mariadb( brew info mariadb

    跟随 installation guide :

    git clone https://github.com/DMPRoadmap/roadmap.git
    cd roadmap
    cp config/database_example.yml config/database.yml
    cp config/secrets_example.yml config/secrets.yml
    cp config/branding_example.yml config/branding.yml
    cp config/initializers/devise.rb.example config/initializers/devise.rb
    cp config/initializers/recaptcha.rb.example config/initializers/recaptcha.rb
    cp config/initializers/wicked_pdf.rb.example config/initializers/wicked_pdf.rb
    bundle install
    rake secret
    vi config/secrets.yml # put the secret generated above into `config/secret.yml`
    rake db:create
    rake db:schema:load
    rake db:migrate
    

    rake db:迁移

     ActiveRecord::Schema.define(version: 20180508151824) do
    
       create_table "annotations", force: :cascade do |t|
    -    t.integer  "question_id"
    -    t.integer  "org_id"
    -    t.text     "text"
    -    t.integer  "type",        default: 0, null: false
    +    t.integer  "question_id", limit: 4
    +    t.integer  "org_id",      limit: 4
    +    t.text     "text",        limit: 65535
    +    t.integer  "type",        limit: 4,     default: 0, null: false
         t.datetime "created_at"
         t.datetime "updated_at"
       end
    
    -  add_index "annotations", ["question_id"], name: "index_annotations_on_question_id"
    +  add_index "annotations", ["org_id"], name: "fk_rails_aca7521f72", using: :btree
    +  add_index "annotations", ["question_id"], name: "index_annotations_on_question_id", using: :btree
    
       create_table "answers", force: :cascade do |t|
    -    t.text     "text"
    -    t.integer  "plan_id"
    -    t.integer  "user_id"
    -    t.integer  "question_id"
    +    t.text     "text",         limit: 65535
    +    t.integer  "plan_id",      limit: 4
    +    t.integer  "user_id",      limit: 4
    +    t.integer  "question_id",  limit: 4
         t.datetime "created_at"
         t.datetime "updated_at"
    -    t.integer  "lock_version", default: 0
    +    t.integer  "lock_version", limit: 4,     default: 0
       end
    
    -  add_index "answers", ["plan_id"], name: "index_answers_on_plan_id"
    -  add_index "answers", ["question_id"], name: "index_answers_on_question_id"
    +  add_index "answers", ["plan_id"], name: "index_answers_on_plan_id", using: :btree
    +  add_index "answers", ["question_id"], name: "index_answers_on_question_id", using: :btree
    +  add_index "answers", ["user_id"], name: "fk_rails_584be190c2", using: :btree
    
       create_table "answers_question_options", id: false, force: :cascade do |t|
    -    t.integer "answer_id",          null: false
    

    其他问题:

    • 为什么要加一堆限制和树呢?
    • 为什么加上这一行: + add_index "annotations", ["org_id"], name: "fk_rails_aca7521f72", using: :btree ? 它以前不在这里
    1 回复  |  直到 6 年前
        1
  •  2
  •   Henry Yang    6 年前

    你的 db/schema.rb 文件表示Rails所看到的数据库结构。每当您做任何可能改变数据库的事情时,Rails都会查询数据库的当前结构,并将该结构写入 .

    Rails无法知道迁移是否会改变数据库的结构。如果您只使用通常的迁移帮助程序,那么理论上,它可以知道模式是否发生了变化,但是 connection.execute 用于将SQL直接发送到数据库。建筑物 schema.rb 是相对快速的,所以最简单(也是最合理的)的解决方案是每次您 rake db:migrate .

    变更自:

    t.integer  "question_id"
    

    t.integer  "question_id", limit: 4
    

    表明原来的 模式.rb 来自PostgreSQL(它不支持 :limit 整数列上的选项),但您的选项来自MariaDB(它确实有 整数列上的s)。其他更改的来源相同:PostgreSQL以一种方式执行,MariaDB以另一种方式执行。


    我需要的不仅仅是一个评论,为一些评论澄清一些事情,所以这里。

    btree MariaDB(MySQL的一个分支)支持索引,在这种特定情况下 fk_rails_584be190c2 顾名思义,它与MariaDB(或ActiveRecord with MariaDB)处理外键的方式有关。如果你看看 bottom of the original schema.rb :

    add_foreign_key "annotations", "orgs"
    ...
    add_foreign_key "answers", "users"
    ...
    

    上的FK answers.users fk U铁路公司