是否可以在 Rails 迁移中使用外部 SQL 文件?

发布于 2024-07-30 07:21:21 字数 151 浏览 1 评论 0原文

我必须创建一个 Rails 迁移,它会创建许多触发器和存储过程。

通常,人们会使用 execute 方法来执行此操作,但由于语句的大小,我宁愿将它们保存在外部文件中并从迁移中引用它。

我怎样才能做到这一点? 有可能吗?

I have to create a Rails migration which creates many triggers and stored procedures.

Normally one would do that using the execute method, but because of the size of the statements, I'd rather keep them in an external file and reference it from the migration.

How can I do that? Is it even possible?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

扭转时空 2024-08-06 07:21:21

您可以将它们存储在文本文件中并通过 File 对象读取它们。

sql = ""
source = File.new("./sql/procedures.sql", "r")
while (line = source.gets)
  sql << line
end
source.close
execute sql

它很丑,但是有效。 我强烈建议将存储过程/触发器保留在迁移中,以便于回滚。

如果您使用“外部文件”方法,则每次迁移都需要维护两个额外的文件,一个用于添加所有内容,另一个用于在出现以下情况时放入:

rake db:rollback

You can just store them in a text file and read them in via a File object.

sql = ""
source = File.new("./sql/procedures.sql", "r")
while (line = source.gets)
  sql << line
end
source.close
execute sql

It's ugly, but works. I'd strongly recommend keeping the stored procedures/triggers inside migrations for easy rollbacks.

If you do the "external file" method, you'll need to maintain two additional files per migration, one for adding all the stuff, and one for dropping in in case of a:

rake db:rollback
半窗疏影 2024-08-06 07:21:21

我在需要的地方做了以下操作:

class RawSqlMigration < ActiveRecord::Migration
  def up
    execute File.read(File.expand_path('../../sql_migrations/file.sql', __FILE__))
  end
end

I did the following where we needed:

class RawSqlMigration < ActiveRecord::Migration
  def up
    execute File.read(File.expand_path('../../sql_migrations/file.sql', __FILE__))
  end
end
浅忆流年 2024-08-06 07:21:21

如果文件中只有一条语句,Mike 的答案毫无问题,但如果有更多语句(例如多次插入和更新),ActiveRecord 将失败,因为默认情况下它不支持一次调用多个语句。

一种解决方案是修改 ActiveRecord 以支持多个语句,如此处所述。

另一种解决方案是确保您的 SQL 文件每行仅包含一个语句,并使用类似的循环

source = File.open "db/foo.sql", "r"
source.readlines.each do |line|
  line.strip!
  next if line.empty? # ensure that rows that contains newlines and nothing else does not get processed
  execute line
end
source.close

Mike’s answer works without problems if you have only one statement in the file, but if there is more statements (multiple inserts and updates, for example), ActiveRecord will fail as it doesn’t support multiple statements with one call by default.

One solution would be to modify ActiveRecord to support multiple statements, as instructed here.

Other solution would be to ensure that your SQL file contains only one statement per row and use a loop like

source = File.open "db/foo.sql", "r"
source.readlines.each do |line|
  line.strip!
  next if line.empty? # ensure that rows that contains newlines and nothing else does not get processed
  execute line
end
source.close
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文