rake db :: migrate实际上是如何工作的

时间:2022-08-25 17:26:44

I've just really started with Ruby and Rails, and one of the things that I find myself really enjoying is the conventions it makes you use.

我刚刚开始使用Ruby和Rails,我发现自己真正喜欢的一件事是它让你使用的约定。

I want to mimic that behavior in my own non-Ruby projects.

我想在我自己的非Ruby项目中模仿这种行为。

My question is how does it actually work? I know I can look through the Rails code, but I'm not that far enough in my understanding to know what's going on in it.

我的问题是它是如何实际运作的?我知道我可以浏览一下Rails代码,但是我的理解还不够,知道它里面发生了什么。

I know that it takes a baseline script and then runs update schema changes against it. But how does it know what version it's on? How would I mimic that in another framework / database?

我知道它需要一个基线脚本,然后针对它运行更新架构更改。但它怎么知道它的版本是什么?我如何在另一个框架/数据库中模仿它?

1 个解决方案

#1


21  

Note: This is true so far as Rails 2.x. It may not hold true for rails 3, as I haven't spent as much time with Rails 3 as I would have liked.

注意:就Rails 2.x而言,这是正确的。它可能不适用于rails 3,因为我没有像我希望的那样花费太多时间使用Rails 3。

Rails creates a special hidden table named schema_migrations. This table has a single column named version. And there is a row in this column for every migration you have. The value being the timestamp that matches the migrations filename timestamp.

Rails创建一个名为schema_migrations的特殊隐藏表。该表有一个名为version的列。对于每次迁移,此列中都有一行。该值是与迁移文件名时间戳匹配的时间戳。

When you migrate, it looks through all your migrations in chronological order (also happens to be alphabetical order due to the timstamp based naming convention). For every migration it looks for a matching row in the schema_migrations table. If it fails to find one, then it runs that migration, and adds the timestamp the table. If it does find one, it assumes it already ran and simply skips it.

迁移时,它会按时间顺序查看所有迁移(由于基于timstamp的命名约定,也会按字母顺序排序)。对于每次迁移,它都会在schema_migrations表中查找匹配的行。如果找不到,则运行该迁移,并添加表的时间戳。如果确实找到一个,它会认为它已经运行并且只是跳过它。

The result is that 2 developers can both commit migrations in any order, and it's fine. This is because Rails knows exactly what migrations have been run and which haven't, regardless of when your database first saw them.

结果是2个开发人员都可以按任何顺序提交迁移,这很好。这是因为无论数据库何时第一次看到它们,Rails都确切知道哪些迁移已经运行,哪些没有。

So to do something yourself like this, you simply need a way to permanently store this state about which steps been taken and which have not.

所以要自己做这样的事情,你只需要一种方法来永久存储这个状态,说明采取了哪些步骤,哪些步骤没有采取。

#1


21  

Note: This is true so far as Rails 2.x. It may not hold true for rails 3, as I haven't spent as much time with Rails 3 as I would have liked.

注意:就Rails 2.x而言,这是正确的。它可能不适用于rails 3,因为我没有像我希望的那样花费太多时间使用Rails 3。

Rails creates a special hidden table named schema_migrations. This table has a single column named version. And there is a row in this column for every migration you have. The value being the timestamp that matches the migrations filename timestamp.

Rails创建一个名为schema_migrations的特殊隐藏表。该表有一个名为version的列。对于每次迁移,此列中都有一行。该值是与迁移文件名时间戳匹配的时间戳。

When you migrate, it looks through all your migrations in chronological order (also happens to be alphabetical order due to the timstamp based naming convention). For every migration it looks for a matching row in the schema_migrations table. If it fails to find one, then it runs that migration, and adds the timestamp the table. If it does find one, it assumes it already ran and simply skips it.

迁移时,它会按时间顺序查看所有迁移(由于基于timstamp的命名约定,也会按字母顺序排序)。对于每次迁移,它都会在schema_migrations表中查找匹配的行。如果找不到,则运行该迁移,并添加表的时间戳。如果确实找到一个,它会认为它已经运行并且只是跳过它。

The result is that 2 developers can both commit migrations in any order, and it's fine. This is because Rails knows exactly what migrations have been run and which haven't, regardless of when your database first saw them.

结果是2个开发人员都可以按任何顺序提交迁移,这很好。这是因为无论数据库何时第一次看到它们,Rails都确切知道哪些迁移已经运行,哪些没有。

So to do something yourself like this, you simply need a way to permanently store this state about which steps been taken and which have not.

所以要自己做这样的事情,你只需要一种方法来永久存储这个状态,说明采取了哪些步骤,哪些步骤没有采取。