web-dev-qa-db-ja.com

Ectoで2つの列に一意の制約を作成する

Ectoの2つの列に一意のインデックスを作成するには、これに対応します。

CREATE TABLE someTable (
    col1 int NOT NULL,
    col2 int NOT NULL,
    primary key (col1, col2)
)

28
2083

パトリックの答えを少しフォローアップ

モデルで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
87
TheSquad

を使用して、複数の行にわたって一意のインデックスを作成できます。

create unique_index(:some_table, [:col1, :col2])

複合キーが必要な場合は、 execute/1 SQLを手動で実行します。ただし、コンポジットキーがEctoでどのように機能するかはわかりませんが、通常はテーブルごとに標準のシリアルIDを使用します。

複合キーアプローチを使用する必要がある場合、NOT NULL制約は必要ありません。複合キーは、列がnullでないことを既に強制する必要があります。

12
Patrick Oscity

unique_indexは、not質問の例に示されているように、複合主キーを作成します。ユニーク制約を作成します。

複合主キーを作成する場合(注:Ectoを使用する場合はお勧めしません)、 詳細はこちら

移行:

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はあなたが望むものですが。

4
Oskar