Padle很好,但是南瓜(铁轨迁移)更有趣
#database #ruby #rails

我最近听说过挤压轨道迁移。因此,我想尝试一下它,因为我喜欢学习内部工作的工作方式,而且对铁轨迁移一无所知。这是学习迁移并尝试挤压一些的时间和地点!

一般迁移

在其他一切之前,它可能很愚蠢,但是让我们重新定义并了解它们是什么迁移以及它们有帮助的原因。

如果您查看rails documentation
迁移是一种以一致的方式更改数据库架构的便捷方法。
您可以将每个迁移视为数据库的新“版本”。

此外,它们通常是用代码编写的,该代码可以进行评论,正如我们所说,数据库的版本控制会更改。

铁路迁移内部

运行迁移时,有几件事要理解。

首先,在您的数据库中,有一个由Rails维护和使用的表,这与您的模型无关。该表是schema_migrations;除了您运行的迁移版本外,该表中没有什么。

您可以通过Rails App中的模型访问此表:
例如,转到模型文件夹并创建一个schema_migration.rb文件。

class SchemaMigration < ActiveRecord::Base
end

已经存在实施;您可以看到其文档here。但是您将无法访问它:)

现在您可以像其他任何模型一样使用它:

irb(main):001:0> SchemaMigration.all
  SchemaMigration Load (0.6ms)  SELECT "schema_migrations".* FROM "schema_migrations"
=> []

这里什么都没有;现在是正常的。我们没有进行任何迁移;让我们创建一个。

> rails g model user name:string
      invoke  active_record
      create    db/migrate/20230723165832_create_users.rb
      create    app/models/user

现在,我们可以添加具有时间戳名称列的用户表:

class CreateUsers < ActiveRecord::Migration[7.0]
  def change
    create_table :users do |t|
      t.string :name

      t.timestamps
    end
  end
end

如果您不运行迁移,仍然没有任何东西:

irb(main):001:0> SchemaMigration.all
  SchemaMigration Load (1.0ms)  SELECT "schema_migrations".* FROM "schema_migrations"
=> []

但是,当您运行它并检查schema_migration表时,您将具有迁移的版本。

> rails db:migrate
== 20230723165832 CreateUsers: migrating ==================================
-- create_table(:users)
   -> 0.0137s
== 20230723165832 CreateUsers: migrated (0.0137s) =========================

> bin/rails c

irb(main):001:0> SchemaMigration.all
  SchemaMigration Load (0.5ms)  SELECT "schema_migrations".* FROM "schema_migrations"
 => [#<SchemaMigration:0x0000000112c4dbd8 version: "20230723165832">]

现在我们已经了解了,挤压我们的迁移很容易。

正如我说的那样,Padle是好南瓜更好

什么是挤压?最终将是

但首先,让我们创建另一个迁移:

> rails g model company name:string
      invoke  active_record
      create    db/migrate/20230724134526_create_companies.rb
      create    app/models/user

这创建了此文件:

class CreateCompanies < Rails::Migration[7.0]
    def change
        create_table :companies do |t|
            t.string :name
            t.timestamps
        end
    end
end

运行迁移后,如果您检查schema_migrations表。您会看到一个超级酷的新示意图!

irb(main):001:0> SchemaMigration.all
  SchemaMigration Load (0.5ms)  SELECT "schema_migrations".* FROM "schema_migrations"
 => [#<SchemaMigration:0x0000000112c4dbd8 version: "20230723165832">,#<SchemaMigration:0x0000000az2c4efd8 version: "20230724134526">]

现在有了我们的两个迁移,我们已经可以挤压它们了。它比您想象的要容易!

运行迁移后,您最终会根据自己选择拥有的schema.rbschema.sql

将其内容添加并将其复制并粘贴到您的上一次迁移的更改方法中:
DB/Migrate/20230724134526_CREATE_COMPANIES.RB

我们可以重命名或不依赖您,例如:
DB/Migrate/20230724134526_squash_table.rb

class SquashTable < Rails::Migration[7.0]
    def change 
      create_table "table1", force: :cascade do |t|
        t.string "name"
      end

      create_table "table2", force: :cascade do |t|
        t.string "name"
      end

      create_table "table3", force: :cascade do |t|
        t.string "name"
        t.datetime "created_at", null: false
        t.datetime "updated_at", null: false
      end
  end
end

然后您可以删除第一个迁移并重新迁移迁移!

什么也没发生,对吗?确实,这确实是正常的,schema_migrations表已经运行了此迁移。即使我们重命名它,此迁移的版本也没有改变,因此不会重新运行。除非您删除数据库并这样运行迁移:

> rails db:drop db:create db:migrate
== 20230723165832 CreatePalourdes: migrating ==================================
-- create_table("table1", {:force=>:cascade})
   -> 0.0031s
-- create_table("table2", {:force=>:cascade})
   -> 0.0018s
-- create_table("table3", {:force=>:cascade})
   -> 0.0017s
== 20230723165832 CreateTables: migrated (0.0066s) =========================

这将像以前一样运行,除了您不会被迫加载数千个迁移,并且它将在本地和您的CI中运行得更快。

结论

如您所见,铁轨迁移和压制它们并不令人恐惧。

在本文中,我们更好地理解了铁轨的迁移以及如何挤压它们以提高性能。

我敢肯定,您会同意理解Rails Internals令人兴奋的事实,请参见下一篇文章。 :)

如果您有任何疑问或提示,请随时发表评论:)。

保持联系

在Twitter上:@yet_anotherDev

lyntededin:Lucas Barret