2
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Django】複合主キー制約は使えない?The model cannot have more than one field with 'primary_key=True'.と表示された場合

Posted at

概要

  • Djangoでは複合主キー制約がないらしいということがわかりました。
  • 本記事では、複合主キー制約に関して遭遇したエラーの原因と解決方法を記載します。

エラー内容

  • Customerモデル(テーブル)でPrimary Keyを2つのフィールド(カラム)に設定。
  • その状態でマイグレートを実施すると、以下のエラーが出てきました。
SystemCheckError: System check identified some issues:

ERRORS:
customer.Customer: (models.E026) The model cannot have more than one field with 'primary_key=True'.

原因

  • Djangoの設計思想では複合主キー制約がないらしい。
  • Djangoで直接のサポートはないので、複数のフィールドを組み合わせたユニーク制約を使用することで実現できます。
  • 解決策は、以下の記事を参考にしました。

解決策

  • まず、idフィールドとかで良いのでサロゲートキーを追加します。
    • サロゲートキー(代理キー)とは、データベース内での検索や参照を容易にするために使用されるもので、対象のデータとは直接関係のない特に意味を持たない主キーのこと。一意である必要があるため、データの重複や不整合を防止することができます。
  • 次に、UniqueConstraintを定義して複合主キー制約を設定します。
    • 複数のフィールドを組み合わせて一意性を確保する制約です。
    • モデルのMetaクラス内で定義します。
    • fields引数に一意の制約に含めるフィールドをリストで指定すればOKです。
    • unique_together属性は現在非推奨となっています。
  • コードとしては以下のようになります。
models.py
from django.db import models


class Customer(models.Model):
    id = models.IntegerField(db_column="id",
                                  primary_key=True)
    abc_id = models.CharField(db_column="abc_id",
                                  max_length=6,
                                  null=False)
    xyz_cd = models.CharField(db_column="xyz_cd",
                                max_length=5,
                                null=False)
    customer_key = models.CharField(db_column="customer_key",
                                max_length=100,
                                null=False)
    create_date = models.CharField(db_column='create_date',
                                   max_length=100,
                                   default='',
                                   null=True)
    update_date = models.CharField(db_column='update_date',
                                   max_length=100,
                                   default='',
                                   null=True)

    class Meta:
        constraints = [
           # abc_idとxyz_cdでユニーク制約
           models.UniqueConstraint(fields=['abc_id', 'xyz_cd'], name='unique_customer')
        ]
        db_table = 'customer'

  • これで、abc_idxyz_cdの組み合わせが一意であることを保証するユニーク制約が完成しました。
2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?