Ecto 在外键关系迁移期间引用另一个模式

Ecto Referencing Another Schema During Migration for Foreign-Key Relationship

我们正在使用基于模式的多租户数据库。我们在 Elixir 堆栈上,在 Phoenix 框架项目中使用 Postgres、Ecto 和 Triplex。

我们使用默认架构 public 来存储常用数据,例如用户和组织。特别是,我们在 Organisations table 中有一个 tenant_prefix 列,我们用它来将用户映射到他们的租户。

在租约中,我们针对租户 tables。例如,我们有一个 Products table。创建新组织时,我们使用 Triplex 创建模式和 运行 租户迁移,这会创建特定于租户的 table,例如 Products.

作为视觉效果,数据库如下所示:

- app_database
  - public
    - users
    - organisations
    - organisations_users

  - tenant1
    - products
    - (other tables...)

  - tenant2
     - products
     - (other tables...)

Products 迁移看起来像这样。

 1 defmodule App.Repo.Migrations.CreateProducts do
 2  use Ecto.Migration
 3
 4  def change do
 5    create table(:products) do
 6      add :title, :string
 7      add :description, :string
 8      add :organisation_id, references(:organisations, on_delete: :nothing), null: false
 9
10      timestamps()
11    end
12
13    create index(:products, [:organisation_id])
14  end
15 end

现在,由于 Line 8,它无法 运行。报告的错误是:ERROR 42P01 (undefined_table) relation "59ef85c702d24d0fac5c7e425d0d3d44.organisations" does not exist

租户前缀是一个 UUID。

所以总结一下,我们想知道如何引用public.organisations table来定义tenant.products中的外键关系。

我不确定它是否有帮助,但我认为您应该在参考文献中使用 prefix 选项。您可以查看文档以获取更多参考。

https://hexdocs.pm/ecto_sql/Ecto.Migration.html#references/2

根据我的理解,第 8 行应该是这样的

add :organisation_id, references(:organisations, on_delete: :nothing, prefix: "public"), null: false

至于语法,如果 "public" 导致语法错误,请使用 :public

为什么需要这个?

通常当 prefix 默认为 nil 时,在这种情况下,ecto 肯定会在您当前的模式名称前加上 table 名称,这在您的情况下会发生。通过设置此前缀选项,您可以根据您的要求设置自定义值。

如果有效请发表评论。因为我也很好奇...