Closed suzdalnitski closed 1 year ago
For dynamic event stores you cannot use the Mix tasks provided by the event store library. Instead you will need to create your own Mix task - or release tasks module for deployment - and manually call the event store tasks to create, init, and migrate the separate event store schemas.
You need to include the dynamic schema in the event store's config:
alias EventStore.Tasks.{Create, Init, Migrate}
alias MyApp.Commanded.EventStore
for schema <- ["eventstore_default", "eventstore_other"] do
config = EventStore.config() |> Keyword.merge(pool_size: 1, schema: schema)
Create.exec(config, quiet: true)
Init.exec(config, quiet: true)
Migrate.exec(config, quiet: true)
end
For deployment using a release tasks module see the Phoenix deploying with releases documentation where they have an example of Ecto migrations and custom commands. Example show below.
defmodule MyApp.Release do
alias EventStore.Tasks.{Create, Init, Migrate}
alias MyApp.Commanded.EventStore
@app :my_app
def migrate do
load_app()
for schema <- ["eventstore_default", "eventstore_other"] do
config = EventStore.config() |> Keyword.merge(pool_size: 1, schema: schema)
Create.exec(config, quiet: true)
Init.exec(config, quiet: true)
Migrate.exec(config, quiet: true)
end
end
defp load_app do
Application.load(@app)
end
end
Then you'd run:
$ MIX_ENV=prod mix release
$ _build/prod/rel/my_app/bin/my_app eval "MyApp.Release.migrate"
Worked like a charm, thank you!
I think this information should be somewhere public, probably in the guides.
For anyone curious, here's what I modified my (autogenerated, as per the guide referred to above) releases module into for deployment using elixir releases
defmodule MyApp.Release do
@moduledoc """
Used for executing DB release tasks when run in production without Mix
installed.
"""
alias EventStore.Tasks.{Create, Init, Migrate}
@app :my_app
def migrate do
load_app()
for repo <- repos() do
{:ok, _, _} = Ecto.Migrator.with_repo(repo, &Ecto.Migrator.run(&1, :up, all: true))
end
end
def rollback(repo, version) do
load_app()
{:ok, _, _} = Ecto.Migrator.with_repo(repo, &Ecto.Migrator.run(&1, :down, to: version))
end
def setup_event_stores do
load_app()
for event_store <- event_stores() do
config = event_store.config()
Create.exec(config, quiet: true)
Init.exec(config, quiet: true)
Migrate.exec(config, quiet: true)
end
end
defp repos do
Application.fetch_env!(@app, :ecto_repos)
end
defp event_stores do
Application.fetch_env!(@app, :event_stores)
end
defp load_app do
Application.load(@app)
end
end
setup_event_stores/0
is the interesting function
Then I ran
$ MIX_ENV=prod mix release
$ _build/prod/rel/my_app/bin/my_app eval "MyApp.Release.migrate"
$ _build/prod/rel/my_app/bin/my_app eval "MyApp.Release.setup_event_stores"
Hi,
I'm trying to start multiple Commanded applications and EventStores dynamically (one EventStore per Commanded Application). As far as I understand, Commanded will start the event store automatically whenever an application is started. However once I try dispatching commands, I get an error:
relation "event_store_default.streams\ does not exist
. Which makes sense, because I haven't created/initialized the event stores using the other schemas.How do I configure the
event_stores
to use a different schema per event store? I've tried:And then ran
event_store.create
, which didn't work, because it expects modules, and I'm not sure where to put theschema
config option.My Commanded application:
I've been following the guide here, but it didn't mention anything about creating/initializing the event stores: https://github.com/commanded/commanded-eventstore-adapter/blob/master/guides/Dynamic%20Event%20Store.md
Thanks!