在 Ecto 中一起对两列创建唯一约束
Creating a unique constraint on two columns together in Ecto
如何在 Ecto 中的两列上创建唯一索引,对应于此:
CREATE TABLE someTable (
col1 int NOT NULL,
col2 int NOT NULL,
primary key (col1, col2)
)
?
您可以使用
跨多行创建唯一索引
create unique_index(:some_table, [:col1, :col2])
我想如果你想要复合键,你需要手动使用 execute/1
到 运行 你的 SQL。虽然不确定复合键与 Ecto 的配合情况如何,但我通常只坚持每个 table.
的标准序列号
如果您应该使用组合键方法,我认为 NOT NULL
约束是不必要的。复合键应该已经强制列不为空。
对 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
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
就是您想要的。
这是一个旧的 post,但我 运行 今天进入这个。请记住,唯一的 constraint 与唯一的 index 不同(至少,并非在所有版本的 PostGres 中——似乎有一些运动)。在 Ecto 中,目前添加非索引约束的唯一方法似乎是在迁移中使用 execute/1
,例如
defmodule YourMigration do
use Ecto.Migration
def change do
execute(
"ALTER TABLE pre.yourtable ADD CONSTRAINT something UNIQUE (something)"
)
end
end
如何在 Ecto 中的两列上创建唯一索引,对应于此:
CREATE TABLE someTable (
col1 int NOT NULL,
col2 int NOT NULL,
primary key (col1, col2)
)
?
您可以使用
跨多行创建唯一索引create unique_index(:some_table, [:col1, :col2])
我想如果你想要复合键,你需要手动使用 execute/1
到 运行 你的 SQL。虽然不确定复合键与 Ecto 的配合情况如何,但我通常只坚持每个 table.
如果您应该使用组合键方法,我认为 NOT NULL
约束是不必要的。复合键应该已经强制列不为空。
对 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
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
就是您想要的。
这是一个旧的 post,但我 运行 今天进入这个。请记住,唯一的 constraint 与唯一的 index 不同(至少,并非在所有版本的 PostGres 中——似乎有一些运动)。在 Ecto 中,目前添加非索引约束的唯一方法似乎是在迁移中使用 execute/1
,例如
defmodule YourMigration do
use Ecto.Migration
def change do
execute(
"ALTER TABLE pre.yourtable ADD CONSTRAINT something UNIQUE (something)"
)
end
end