将 Postgres 包装成专用的 Phoenix App

Wrap Postgres into a dedicated Phoenix App

目标:有一个 phoenix 应用程序 (#1),它有空的(没有表)Postgres,并且在第一次启动时等待进一步设置。一旦它通过 http 从其他 phoenix 应用程序 (#2) 收到迁移和 model/schema 文件,它 运行s 迁移,开始 supervisor(App1.Repo, []), 并且所有收到来自应用程序 #2 的 models/schemas将状态置于 worker(App1.Models, []),以便应用程序 #1 可以处理 Repo.all(User) 之类的查询。然后,应用程序 #1 监听来自应用程序 #2 的请求并在 Postgres 中执行更改。

原因:想法是将数据库与应用程序 #2 完全隔离,这样当它需要来自数据库的东西时,它只向应用程序 #1 发送 Ecto 查询,并且应用程序 #1 能够执行该查询并 return 结果。但是,可以为不同的应用程序生成应用程序 #1 副本,即应用程序 #2、#3、#4,它们都有不同的 models/schemas,并且在第一次连接时提供它们的数据库设置(models/migrations)以应用程序 #1,它使用这些设置准备其 Postgres,然后只接受数据库查询。


示例:

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

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

第 3 步:应用程序 #1 使用 Ecto、Repo 和来自应用程序 #2 的新 User 模型启动 GenServer(进程?)并侦听传入请求.

第 4 步:应用程序 #1 接收请求、运行s 查询和 returns 其数据库中所有用户的列表。

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

问题:

  1. 首先,有没有可能做这样的事情?还是想法有什么根本性的问题?
  2. 应用程序 #1 运行 如何在没有 start/stopping 服务器的情况下动态接收迁移?我们可以将迁移文件(从应用程序#2 收到)放在某个目录中,然后 运行 类似于 Mix.Tasks.Ecto.Migrate.run() 到 运行 所有迁移吗?
  3. 已解决 App #1 可以编译 models/schemas(从 App #2 收到),使用这些模型启动 GenServer 并使它们可用于 运行命令,例如 Repo.all(User)?或者我们可以使用接收到的models/schemas来动态创建modules, and pass those modules to App1.Repo, in order to perform queries like Repo.all(User), where User is a dynamically generated module? Solution: Using logic from ,我能够动态创建模块,然后使用它们来执行查询。

我可能对一些事情感到困惑,但我相信解决这些问题将有助于实现目标...?任何帮助表示赞赏!

  1. 虽然我很难想象这种架构的好处,但这确实是可能的。

  2. 当然可以,为什么不呢?

使用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/* 而不是重新发明轮子。

这样可以使用 App1App2 中的代码来处理 models/schemas。不过,也许我误解了这里的目标,但由于它已经标记为已解决,所以我会将我的评论作为附加建议。