【问题标题】:Ecto Referencing Another Schema During Migration for Foreign-Key Relationship外键关系迁移期间 Ecto 引用另一个模式
【发布时间】:2021-05-17 01:21:55
【问题描述】:

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

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

在租约中,我们使用特定于租户的表格。例如,我们有一个Products 表。创建新组织时,我们使用 Triplex 创建架构并运行租户迁移,从而创建特定于租户的表,例如 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 表来定义tenant.products 中的外键关系。

【问题讨论】:

    标签: postgresql phoenix-framework ecto


    【解决方案1】:

    我不确定它是否有帮助,但我认为您应该在引用中使用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

    为什么需要这个?

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

    如果可行,请发表评论。因为我也很好奇……?

    【讨论】:

    • 就是这样。谢谢!
    猜你喜欢
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-07
    • 1970-01-01
    • 2015-10-29
    • 2017-10-24
    • 2020-06-27
    相关资源
    最近更新 更多