ruby-on-rails 在迁移中执行原始SQL:将SQL语句作为字符串保存在迁移中,还是作为代码保存在单独的SQL文件中?

h5qlskok  于 2023-02-10  发布在  Ruby
关注(0)|答案(1)|浏览(141)

在数据库中,我有多个具有大定义的物化视图。我还有多个使用DROPCREATE语句更改其中一些物化视图的定义的迁移。因此,我们经常一次又一次地删除/重新创建相同的视图,只做一些小的更改。这些(相当庞大的)语句现在存储在字符串中:

class MyMigrationName < ActiveRecord::Migration[5.2]

  def up
    sql = <<~SQL
      ...
      create materialized view if not exists foo_1 as ... ;
      create materialized view if not exists foo_2 as ... ;
      ...
    SQL
    execute sql
  end

  def down
    ...
  end

我正在考虑从当前的方法切换到另一种方法,即SQL代码存储在单独的SQL文件中,例如db/migrate/concerns/create_foo_matviews.sql。代码从文件中读取并在迁移内部执行,如下所示:

class MyMigrationName < ActiveRecord::Migration[5.2]

  def up
    execute File.read(File.expand_path('./concerns/create_foo_matviews.rb', __FILE__))
  end

  def down
    ...
  end

这种方法的优点是:

  • 使用git diff可以更容易地看到新旧SQL代码之间的差异(考虑到物化视图的定义很大,但迁移中的实际更改相对较小,这一点尤其重要)。
  • SQL文件将语法突出显示添加到SQL代码中。
  • 如果我只更改SQL文件中的相关部分,那么复制/粘贴的代码就会更少。

这个提议的方法是否有任何问题?如果有,什么是最大化可维护性的替代解决方案?

另见

w8biq8rn

w8biq8rn1#

我会把它留在迁移中。
这主要是因为迁移包含了实际构成数据库更改的所有内容。您需要有两个外部SQL文件(updown),我需要先搜索/查找这两个文件,然后才能理解迁移的作用。
根据所使用的编辑器,您将获得(有限的)语法高亮显示x1c 0d1x
执行自定义SQL的迁移看起来都一样,只是外部文件的名称不同。
你想解决什么问题?只是“笨重”的字符串?我不认为这是一个值得花费大量时间的问题(老实说,一旦迁移运行,无论如何你都不会再回到它)。只是简单的事情:heredoc字符串中的SQL。
还有一些gem允许您使用普通的迁移代码创建(物化)视图(通过添加对create_view或类似代码的支持),但我不会为这么简单的代码添加额外的依赖项。
如果还没有完成,也可以考虑从 schema.rb 更改为 structure.sql

相关问题