SQLのuniqueはDjangoではunique_together

以下DBはすべてPostgreSQLを使い、 SQLとORMでの挙動の比較をしました


SQLの unique制約はdjangoではunique_togetherに対応するらしい。たとえば、SQLの

CREATE TABLE contacts (
    id integer primary key,
    name text,
    phone_number integer,
    UNIQUE(name, phone)
)
と、Djangoのmodel

class Contacts:
    name=models.CharField(max_length=128)
    phone_number=models.IntegerFIeld()

    Meta:
        unique_together=(name, phone)

は同じこと。上記2つの例では、Uniqueの制約は、ペアの組み合わせに対してかかる。なので、
 ('Alice', 00000000000)
 ('Alice', 00000000001)
の2つは、データベースへの追加が可能である。また、Djangoでは primary_key=True は null=Fals, unique=True を意味する[1]。

primary_key=True implies null=False and unique=True. Only one primary key is allowed on an object.

ちなみに、カラムごとにunique制約をかけた場合、SQLもDjango ORMも同じように、カラムそれぞれについての重複を許さない、上記より、さらに厳しい制約となる。たとえば、次のmodelでは、nameもphone_numberもそれぞれで、uniqueであることを求められている。(name, phone_number)のペアでuniqueであることよりも厳しい制約がかかる。

class Contacts:
    name=models.CharField(max_length=128, unique=True)
    phone_number=models.IntegerFIeld(unique=True)
次のSQLの挙動も同様である。
CREATE TABLE contacts (
    id integer primary key,
    name text unique,
    phone_number integer unique
)
下記は、PostgreSQLで確認した例である。

postgres=# create table test(
    name text unique,
    address text unique)
;
CREATE TABLE
postgres=# insert into test(name, address) VALUES ('alice','NY'), ('alice', 'LA');
ERROR:  duplicate key value violates unique constraint "test_name_key"
DETAIL:  Key (name)=(alice) already exists.



  1. https://docs.djangoproject.com/en/2.0/ref/models/fields/#primary-key 

コメント

このブログの人気の投稿

株式会社GAIAの説明会で驚いた - パチンコホールの売上や給与 -

Python機械学習scikit-learn入門 SVMの学習とクロス・バリデーション (K-fold)