Comment créer un index unique sur deux colonnes dans Ecto, ce qui correspondrait à ceci:
CREATE TABLE someTable (
col1 int NOT NULL,
col2 int NOT NULL,
primary key (col1, col2)
)
?
Un petit suivi de la réponse de Patrick
Utiliser uniquement create unique_index sur votre modèle générera finalement une exception au lieu de vous donner une erreur.
Pour obtenir une erreur, ajoutez une contrainte sur votre ensemble de modifications, mais en tant que paramètre, vous pouvez donner le nom d'index créé par unique_index.
Donc dans votre fichier de migration:
create unique_index(:your_table, [:col1, :col2], name: :your_index_name)
Puis dans votre changeset:
def changeset(model, param \\ :empty) do
model
|> cast(params, @required_fields, @optional_fields)
|> unique_constraint(:name_your_constraint, name: :your_index_name)
end
Vous pouvez créer un index unique sur plusieurs lignes avec
create unique_index(:some_table, [:col1, :col2])
Je suppose que si vous voulez avoir des clés composites, vous devez utiliser execute/1
pour exécuter votre SQL manuellement. Je ne sais pas si les clés composites fonctionnent bien avec Ecto, je reste généralement avec l'ID série standard par table.
Si vous optez pour l'approche clé composite, je pense que le NOT NULL
les contraintes ne sont pas nécessaires. La clé composite doit déjà imposer que les colonnes ne sont pas nulles.
unique_index
ne créerait pas une clé primaire composite comme le montre l'exemple de la question. Cela crée une contrainte unique.
Si vous souhaitez créer une clé primaire composite (remarque: non recommandé lorsque vous travaillez avec Ecto), il y a plus d'informations ici :
Migration:
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
...
Schéma:
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
...
Dans la plupart des cas unique_index
c'est ce que vous voulez.