将Postgres包装成专用的Phoenix应用程序

时间:2018-05-27 08:09:21

标签: postgresql elixir phoenix-framework ecto

目标:拥有一个凤凰应用程序(#1),它有空(没有表格)Postgres并且在第一次启动时等待进一步设置。一旦它通过来自其他凤凰应用程序(#2)的http接收迁移和模型/模式文件,它就会运行迁移,启动supervisor(App1.Repo, []),,所有从app#2收到的模型/模式都会进入worker(App1.Models, [])状态,以便app#1可以处理Repo.all(User)之类的查询。然后,app#1侦听来自应用#2的请求并在Postgres中执行更改。

原因:想法是将数据库与应用程序#2完全隔离,这样当它需要来自数据库的内容时,它只会向应用程序#1和应用程序#1发送Ecto个查询能够执行该查询并返回结果。但是,app#1副本可以针对不同的应用程序生成,即app#2,#3,#4,它们都具有不同的模型/模式,并且在第一次连接时为app#1提供其db设置(模型/迁移),使用这些设置准备Postgres,然后只接受数据库查询。

实施例

第1步:应用#1从应用#2接收User模型和相应的迁移文件。

第2步:App#1运行迁移文件以准备Postgres。

第3步:应用#1使用应用#2中的Ecto,Repo和新收到的User模型启动GenServer(进程?),并侦听传入的请求。

第4步:应用#1接收请求,运行查询,并返回其数据库中所有用户的列表。

%{
  query: 'User',
  command: 'all'
 } 
 # Should run by app #1 as Repo.all(User)

问题:

  1. 首先,甚至可以做这样的事情吗?或者这个想法有一些根本问题?
  2. app#1如何在不启动/停止服务器的情况下动态接收迁移?我们是否可以将迁移文件(从应用程序#2接收)放在某个目录中,然后运行类似Mix.Tasks.Ecto.Migrate.run()的内容来运行所有迁移?
  3. 解决 App#1可以编译模型/模式(从应用#2接收),使用这些模型启动GenServer并使其可用于运行命令,如Repo.all(User)?或者我们可以使用收到的模型/模式动态创建modules,并将这些模块传递给App1.Repo,以执行Repo.all(User)之类的查询,其中User是动态生成的模块? 解决方案:使用here中的逻辑,我能够动态创建模块,然后使用它们来执行查询。
  4. 我可能会混淆一些事情,但我相信解决这些问题有助于实现目标......?任何帮助赞赏!

1 个答案:

答案 0 :(得分:2)

  1. 虽然我很难想象这种架构会带来什么好处,但这肯定是可能的。

  2. 当然,为什么不呢?

  3. 使用Ecto.Migrator

    def migrate! do
      path = Application.app_dir(:my_app, "priv/repo/migrations")
      Ecto.Migrator.run(MaApp.Repo, path, :up, all: true)
    end
    
    1. 我会利用ErlangVM,在Node.spawn/*的不同节点上运行远程功能,而不是重新发明轮子。
    2. 这样可以使用来自App2的{​​{1}}中的代码来处理模型/模式。也许我误解了这里的目标,但由于它已经标记为已解决,我会将我的评论作为一个额外的建议。