如何在Ecto中的两列上创建唯一索引,对应于此:
CREATE TABLE someTable (
col1 int NOT NULL,
col2 int NOT NULL,
primary key (col1, col2)
)
答案 0 :(得分:83)
对Patrick的答案进行一点跟进
在模型上仅使用create unique_index最终会抛出异常,而不是给出错误。
要获得错误,请在变更集上添加约束,但作为参数,您可以为unique_index创建索引名称。
所以在您的迁移文件中:
create unique_index(:your_table, [:col1, :col2], name: :your_index_name)
然后在你的变更集中:
def changeset(model, param \\ :empty) do
model
|> cast(params, @required_fields, @optional_fields)
|> unique_constraint(:name_your_constraint, name: :your_index_name)
end
答案 1 :(得分:12)
您可以使用
跨多行创建唯一索引create unique_index(:some_table, [:col1, :col2])
我想如果你想要复合键,你需要使用execute/1
手动运行SQL。不知道复合键与Ecto的工作情况有多好,我通常只是坚持每个表的标准序列号。
如果您应该使用复合键方法,我认为NOT NULL
约束不是必需的。复合键应该已经强制列不为空。
答案 2 :(得分:4)
unique_index
将不创建复合主键,如问题示例中所示。它确实创造了一个独特的约束。
如果您确实想要创建复合主键(注意:使用Ecto时不建议使用),there's more information here:
<强> 迁移: 强>
defmodule HelloPhoenix.Repo.Migrations.CreatePlayer do
use Ecto.Migration
def change do
create table(:players, primary_key: false) do
add :first_name, :string, primary_key: true
add :last_name, :string, primary_key: true
add :position, :string
add :number, :integer
...
<强> 架构: 强>
defmodule HelloPhoenix.Player do
use Ecto.Schema
@primary_key false
schema "players" do
field :first_name, :string, primary_key: true
field :last_name, :string, primary_key: true
field :position, :string
field :number, :integer
...
在大多数情况下,unique_index
就是你想要的。