[英]How to establish_connection with more than one database in parallel in Rails?
I'm building a SaaS where users can create their own websites (like Wix or SquareSpace). 我正在构建一个SaaS,用户可以在其中创建自己的网站(如Wix或SquareSpace)。 That's what happens behind scenes: 这就是幕后发生的事情:
To create a new database and establish connection I do the following: 要创建新数据库并建立连接 ,请执行以下操作:
ActiveRecord::Base.connection.execute("CREATE DATABASE #{name}")
ActiveRecord::Base.establish_connection(<dynamic db data>)
Then I execute sql code in the db by doing: 然后我通过执行以下操作在db中执行sql代码:
sql = File.read(sql_file.sql)
statements = sql.split(/;$/)
statements.pop
ActiveRecord::Base.transaction do
statements.each do |statement|
connection.execute(statement)
end
end
Then I reestablish connection with main db: 然后我重新建立与主db的连接:
ActiveRecord::Base.establish_connection :production
How can I handle many users creating their websites simultaneously without databases conflict? 如何在没有数据库冲突的情况下同时处理许多用户创建网站?
In other words, how can I establish_connection
with more than one database in parallel? 换句话说,我怎么能establish_connection
与并行多个数据库?
NOTE: It is not the same as connecting to multiple databases through database.yml. 注意:它与通过database.yml连接到多个数据库不同。 The goal here is to connect and disconnect to dynamic created databases by multiple users simultaneously. 这里的目标是同时连接和断开多个用户对动态创建的数据库的连接。
This gem may help. 这个宝石可能有帮助。 However,you may need to rename some of your models to use the external database namespace instead of ApplicationRecord
但是,您可能需要重命名某些模型以使用外部数据库命名空间而不是ApplicationRecord
https://github.com/ankane/multiverse https://github.com/ankane/multiverse
I admit that this doesn't answer the core of your initial question but IMO this probably needs to be done via a separate operation, say a pure SQL script triggered somehow via a queue. 我承认这不能回答你的初始问题的核心,但IMO可能需要通过一个单独的操作完成,比如通过队列以某种方式触发的纯SQL脚本。
You could have your rails app drop a "create message" onto a queue and have a separate service that monitors the queue that does the create operations, and then pass a message with info back to the queue. 您可以让rails应用程序将“创建消息”放入队列,并拥有一个单独的服务来监视执行创建操作的队列,然后将带有信息的消息传递回队列。 The rails application monitors the queue for these and then does something with the information. rails应用程序监视队列中的这些,然后对信息执行某些操作。
The larger issue is decoupling your operations. 更大的问题是解耦您的运营。 This will help you down the road with things like maintenance, scaling, etc. 这将帮助您顺利完成维护,缩放等操作。
FWIW here is a really cool website I found recently describing a lot of popular queuing services. FWIW这里是一个非常酷的网站,我最近发现它描述了很多流行的排队服务。
Probably not the best approach but it can be achieved by calling an external script that creates the database, in a separated ruby file: 可能不是最好的方法,但可以通过在分离的ruby文件中调用创建数据库的外部脚本来实现:
Put db creation script inside this file 将db creation脚本放在此文件中
ActiveRecord::Base.connection.execute("CREATE DATABASE #{name}") ActiveRecord::Base.establish_connection(<dynamic db data>)
Execute with Rails Runner 使用Rails Runner执行
rails runner lib/create_database.rb
or with system, if you want to call it from controller 或者使用系统,如果你想从控制器调用它
system("rails runner lib/create_database.rb")
This way you can create and access multiple databases without stopping your main database. 这样,您可以在不停止主数据库的情况下创建和访问多个数据库。
You can pass arguments to your script with ARGV: 您可以使用ARGV将参数传递给脚本:
rails runner lib/create_database.rb db_name
And catch it inside the script with ARGV[0]
: 并使用ARGV[0]
在脚本中捕获它:
name = ARGV[0]
puts name
> db_name
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.