Narven

Narven

Triplex with transactions always returns error on migrate

Hi,

For the last 2 days, I’ve be trying to implement Triplex to add multi-tenancy to my application, and I use transactions a lot, usually with Ecto.Multi.

From the documentation it looks like with triplex I need to use:

    Triplex.create_schema(slug, Project.Repo, fn(tenant, repo) ->
      Repo.transaction(fn ->
        mig = Triplex.migrate(tenant, repo)
        IO.inspect(mig, label: "MIGRATE")

        // Add any ecto operation here...

        tenant
      end)
    end)

My problem is that Triplex.migrate(tenant, repo) is always, always returning:

 {:error,
 "ERROR 42P01 (undefined_table) relation \"prj_c24.schema_migrations\" does not exist\n\n    query: INSERT INTO \"prj_c24\".\"schema_migrations\" (\"version\",\"inserted_at\") VALUES ($1,$2)"}

For me this is an extreme confusing error. It tells nothing about what is happening, (at least for me).

My only migration is this:

defmodule Project.Repo.Migrations.CreateUsersTables do
  use Ecto.Migration

  def change do
    # execute "CREATE EXTENSION IF NOT EXISTS citext", ""

    create table(:users, primary_key: false) do
      add(:id, :uuid, primary_key: true, null: false)
      # add(:email, :citext, null: false)
      add(:hashed_password, :string, null: false)
      add(:first_name, :string, null: false)
      add(:last_name, :string, null: false)
      add(:is_enabled, :boolean, null: false, default: true)
      add(:dob, :date)
      add(:photo, :string, default: "/images/empty.png")
      add(:confirmed_at, :naive_datetime)
      timestamps()
    end

    # create unique_index(:users, [:email])
  end
end

Any help on that error? thanks

PS: The prefix is being created in the database. But migrations are not running.

❯ elixir --version
Erlang/OTP 24 [erts-12.1.5] [source] [64-bit] [smp:16:16] [ds:16:16:10] [async-threads:1] [jit] [dtrace]
Elixir 1.13.0 (compiled with Erlang/OTP 24) 
{:triplex, "~> 1.3.0-rc.1"}

Marked As Solved

al2o3cr

al2o3cr

Yeah, that’s what makes me suspicious about the Repo.transaction in the middle - Triplex.create is defined in a way that’s equivalent to:

Triplex.create_schema(slug, Project.Repo, fn(tenant, repo) ->
  Triplex.migrate(tenant, repo)
end)

Re: your last message about running inside a migration - if this code is inside a migration’s def up, then there’s already a transaction wrapped around the whole thing. You may need to disable that with @disable_ddl_transaction true.

Also Liked

riebeekn

riebeekn

I think the inner transaction is the issue. As mentionned in the Triplex docs the way migrations run was changed in Ecto 3. Since that change I haven’t ever been able to get Triplex.migrate to run within a transaction. Considering create_schema will do a schema drop on any {:error, some_err_message} result… not using a transaction seems an alright way of going about things.

So I would try something along the lines of:

    Triplex.create_schema(slug, Repo, fn tenant, repo ->
      {:ok, _} = Triplex.migrate(tenant, repo)
  
      Repo.transaction(fn ->
        # do other inserts etc. here... such as...
        with {:ok, user} <- insert_some_default_user_on_schema_creation(),
             {:ok, _something_else} <- do_something_else() do
          {:ok, user}
        else
          {:error, error} ->
            Repo.rollback(error)
        end
      end)
    end)

Where Next?

Popular in Questions Top

chrisalley
ExUnit now has describe blocks which is a welcome addition coming from RSpec. In the docs, it states that nested hierarchies of describe ...
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
hariharasudhan94
lets say i have a sample like a = 20; b = 10; if (a &gt; b) do {:ok, "a"} end if (a &lt; b) do {:ok, b} end if (a == b) do {:ok, "equa...
New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New

Other popular topics Top

vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
dogweather
I wrote this comment on r/haskell, and it’s not popular there. :wink: But I think I’m on to something… Haskell reminds me of Java, and e...
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
AstonJ
Seen any cool LiveView demos, sample apps or examples? Please post them here! :003:
New
marius95
Hello everyone, I try to use an Javascript Event Handler in my root.html.leex file. Therefore I created a function in the app.js file: ...
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New

We're in Beta

About us Mission Statement