postgresql - Elixir -- Ecto -- 复合主键和关系

标签 postgresql elixir ecto composite-primary-key

有没有人成功地创建了与具有复合主键的表之间的关系? 我正在努力实现以下目标:

create table(:resources, primary_key: false) do
  add :id, :uuid, primary_key: true
  add :version, :id, primary_key: true 
  # ... other details about the resource
end

create table (:resource_instances, primary_key: false) do
  add :id, :uuid, primary_key: true
  add :resource_id,
      references(:resources, type: :uuid, column: :id),
      null: false

  add :resource_version,
      references(:resources, type: :id, column: :version),
      null: false
  # ... specific details about this instance of the resource
end

运行迁移会产生此日志:

11:24:00.100 [info]  create table my_schema.resources

11:24:00.152 [info]  create table my_schema.resource_instances
** (Postgrex.Error) ERROR 42830 (invalid_foreign_key) there is no unique constraint matching given keys for referenced table "resources"
    (ecto_sql) lib/ecto/adapters/sql.ex:629: Ecto.Adapters.SQL.raise_sql_call_error/1
    (elixir) lib/enum.ex:1336: Enum."-map/2-lists^map/1-0-"/2
    (ecto_sql) lib/ecto/adapters/sql.ex:716: Ecto.Adapters.SQL.execute_ddl/4
    (ecto_sql) lib/ecto/migration/runner.ex:343: Ecto.Migration.Runner.log_and_execute_ddl/3
    (ecto_sql) lib/ecto/migration/runner.ex:117: anonymous fn/6 in Ecto.Migration.Runner.flush/0
    (elixir) lib/enum.ex:1948: Enum."-reduce/3-lists^foldl/2-0-"/3
    (ecto_sql) lib/ecto/migration/runner.ex:116: Ecto.Migration.Runner.flush/0
    (stdlib) timer.erl:166: :timer.tc/1
    (ecto_sql) lib/ecto/migration/runner.ex:25: Ecto.Migration.Runner.run/7
    (ecto_sql) lib/ecto/migrator.ex:342: Ecto.Migrator.attempt/7
    (ecto_sql) lib/ecto/migrator.ex:243: anonymous fn/4 in Ecto.Migrator.do_up/4
    (ecto_sql) lib/ecto/migrator.ex:324: anonymous fn/3 in Ecto.Migrator.run_maybe_in_transaction/6
    (ecto_sql) lib/ecto/adapters/sql.ex:898: anonymous fn/3 in Ecto.Adapters.SQL.checkout_or_transaction/4
    (db_connection) lib/db_connection.ex:1415: DBConnection.run_transaction/4
    (ecto_sql) lib/ecto/migrator.ex:323: Ecto.Migrator.run_maybe_in_transaction/6
    (elixir) lib/task/supervised.ex:90: Task.Supervised.invoke_mfa/2
    (elixir) lib/task/supervised.ex:35: Task.Supervised.reply/5
    (stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3

最佳答案

试试这个:

    create table(:resources, primary_key: false) do
        add :id, :uuid, primary_key: true
        add :version, :id, primary_key: true, auto_generate: true
    end
    create unique_index(:resources, [:id])
    create unique_index(:resources, [:version])

    create table(:resource_instances, primary_key: false) do
        add :resource_id,
            references(:resources, type: :uuid, column: :id),
            null: false
        add :resource_version,
            references(:resources, type: :id, column: :version),
            null: false
    end

似乎因为您正在创建复合键,所以您还需要创建单独的唯一索引才能引用这些索引 所以基本上为各个列添加了 unique_indices

关于postgresql - Elixir -- Ecto -- 复合主键和关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59398230/

相关文章:

mysql - (Ecto.Query.CompileError) 元组只能用于与相同大小的文字元组进行比较。 - 灵药

sql - 如何根据同一表列中的值在 SQL 中进行 SELECT?

postgresql - 如何使用PostgreSQL将数据迁移到远程服务器?

elixir - 如何通过Phoenix应用程序的自定义erl选项?

elixir - 遵循编程 Elixir 书,在列表列表上的守卫方面遇到问题

ubuntu - VM 使用 latin1 的 native 名称编码运行,这可能会导致 Elixir 出现故障,因为它期望使用 utf8

SQL:如何根据不同的现有条件选择字段?

node.js - 在 Github 操作中获取错误 : connect ECONNREFUSED 127. 0.0.1:5432

postgresql - Ecto 中的所有查询

elixir - 如何在 Ecto 模型(或 Elixir 结构)上实现 setter