Goal: Have a phoenix app (#1), that has empty (no tables) Postgres and on first boot waits to be further setup. Once it receives migration and model/schema files via http from other phoenix app (#2), it runs migrations, starts a supervisor(App1.Repo, []),
and all received models/schemas from app #2 puts in state in worker(App1.Models, [])
, so that app #1 can process queries like Repo.all(User)
. Then, app #1 listens for requests from the app #2 and performs changes in Postgres.
Reason: Idea is to isolate DB completely from app #2, so that when it needs something from db, it just sends Ecto
queries to app #1, and app #1 is able to perform that query and return a result. However, app #1 copy can be spawned for different apps, i.e. app #2, #3, #4, which all have different models/schemas, and on first connection provide their db settings (models/migrations) to app #1, which prepares its Postgres with those settings, and then just accept db queries.
Step 1: App #1 receives User
model and respective migration file from app #2.
Step 2: App #1 runs migration file to prepare Postgres.
Step 3: App #1 starts a GenServer (process?) with Ecto, Repo and newly received User
model from app #2 and listens for incoming requests.
Step 4: App #1 receives request, runs query, and returns list of all users in its db.
%{
query: 'User',
command: 'all'
}
# Should run by app #1 as Repo.all(User)
Mix.Tasks.Ecto.Migrate.run()
to run all migrations? Repo.all(User)
? Or can we use received models/schemas to dynamically create 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 here, I was able to dynamically create modules, and then use them to perform queries. I might have confused some things, but I believe solving these problems will help achieve the goal...? Any help appreciated!
Although I could hardly imagine a benefit of this architecture this is surely possible.
Sure, why not?
Use Ecto.Migrator
:
def migrate! do
path = Application.app_dir(:my_app, "priv/repo/migrations")
Ecto.Migrator.run(MaApp.Repo, path, :up, all: true)
end
Node.spawn/*
instead of re-inventing a wheel.That way one might use the the code from App2
from App1
to deal with models/schemas. Maybe I misunderstood the goal here, though, but since it’s already marked a solved, I would live my comment as an additional suggestion.