10

別のモデルで複数の列を参照する外部キーを定義することは可能ですか?

たとえば、1つの外部キーは、製品テーブルの2列のインデックスとSQLステートメントを参照します。

FOREIGN KEY (product_category, product_id) REFERENCES product(category, id)

ところで、私は調べましたがdjango.contrib.contenttypes、それがこの種のシナリオの完璧な解決策ではないと思います。

4

4 に答える 4

15

まだサポートされていません。必要に応じて、チケットとそれを処理するための可能な方法があります。たぶんあなたはカスタムSQLを実行することさえできます

複数列の主キーのサポート

リレーショナルデータベースの設計では、テーブルの主キーとして一連の列を使用します。このセットに複数の列が含まれている場合、それは「複合」または「複合」主キーと呼ばれます。(用語の詳細については、データベースキーについて説明している記事をご覧ください)。現在、Djangoモデルはこのセットの単一の列のみをサポートしており、テーブルの自然な主キーが複数の列である多くの設計を拒否しています。Djangoは現在、これらのスキーマを操作できません。代わりに、冗長な単一列キー(「代理」キー)を導入する必要があります。これにより、アプリケーションは、任意のインスタンスでテーブルに使用するキーについて、任意の、またはその他の方法で不要な選択を行う必要があります。このページでは、Djangoにこれらの複合主キーをサポートさせる方法について説明します。ここで理解するための詳細はたくさんありますが、正しく実行されます。

現在のステータス

現在の状態では、問題は受け入れ/割り当てられ、作業中です。http://github.com/dcramer/django-compositepksに部分的な実装があります。実装により、複合主キーを持つことができます。ただし、ForeignKeyおよびRelatedManagerには複合キーのサポートがありません。結果として、複合主キーを持つモデルから関係をナビゲートすることはできません。

ディスカッション:

DavidCramerの最初のパッチ

複合外部キーAPI設計

チケット

-SqlAlchemyでは、以下で説明するようにこれが可能であり、SqlAlchemyを使用してDjangoのORMを置き換えることができます

外部キーは、 ForeignKeyConstraintオブジェクトを使用してテーブルレベルで定義することもできます。このオブジェクトは、単一列または複数列の外部キーを記述できます。複数列の外部キーは複合外部キーと呼ばれ、ほとんどの場合、複合主キーを持つテーブルを参照します。以下に、複合主キーを持つテーブル請求書を定義します。

invoice = Table('invoice', metadata,
    Column('invoice_id', Integer, primary_key=True),
    Column('ref_num', Integer, primary_key=True),
    Column('description', String(60), nullable=False)
)

次に、請求書を参照する複合外部キーを持つテーブルinvoice_item:

invoice_item = Table('invoice_item', metadata,
    Column('item_id', Integer, primary_key=True),
    Column('item_name', String(60), nullable=False),
    Column('invoice_id', Integer, nullable=False),
    Column('ref_num', Integer, nullable=False),
    ForeignKeyConstraint(['invoice_id', 'ref_num'], ['invoice.invoice_id', 'invoice.ref_num'])
)

参照

于 2012-10-30T06:24:10.887 に答える
0

はい、可能ですが、複数列の制約、つまり外部キーまたは主キーを使用する場合は、複合キーを作成する必要があります。例えば:

CREATE TABLE Student (
   S_num INTEGER,
   S_Cate INTEGER,
   S_descr CHAR(200),
   PRIMARY KEY (S_num, S_Cate))

CREATE TABLE sub_Student (
   Ssub_ID INTEGER PRIMARY KEY,
   Sref_num INTEGER,
   Sref_Cate INTEGER,
   sub_descr CHAR(500),
   FOREIGN KEY (Sref_num, Sref_Cate) REFERENCES Student
      (S_num, S_Cate))
于 2012-11-06T05:40:20.357 に答える
0

とにかく、次のような「Djangoフィクスチャ」を作成できます。

CREATE INDEX product_category_id_id ON product (category_id, id);

これを行うには、モデルが存在product.sqlするサブフォルダーに名前が付けられたファイルを作成する必要があります。sqlフィクスチャは初期syncdbにロードされます。

于 2013-08-30T13:19:02.930 に答える
0

@ pratik-mandrekarの答えは素晴らしいですが、適切な複数列の主キーがなくても、それを指摘したいと思います。djangoは、複数列の外部キーにまたがるクエリに対応できます。これは、変更が許可されていないスキーマのレガシーデータベースに基づく例です。

与えられた:

from django.db import models

class Account(models.Model):
    # Collectively, location_no and occupant_no function as the primary key for Account.
    location_no = models.IntegerField()
    occupant_no = models.SmallIntegerField()

    name = models.CharField(max_length=100)

    class Meta:
        managed = False
        db_table = 'csracct'
        unique_together = (('location_no', 'occupant_no'),)

class Call(models.Model):
    call_id = models.IntegerField(primary_key=True)
    
    # Collectively, location_no and occupant_no act as a foreign key to Account.
    location_no = models.IntegerField()
    occupant_no = models.SmallIntegerField()

    notes = models.TextField()

    class Meta:
        managed = False
        db_table = 'csrcall'

extra()'steve'という名前のアカウントに対する最近の10件の呼び出しを取得するために使用する方法は次のとおりです。

calls = Call.extra(
    tables = ['csracct'],
    where = [
        'csracct.location_no=csrcall.location_no',
        'csracct.occupant_no=csrcall.occupant_no',
        'csracct.name=%s',
        ],
    params = ['steve'],
    ).order_by('-call_id')[:10]

これは最も洗練されたソリューションではありませんがextra()、djangoの基本クエリセットツールキットの一部です。そのため、残りのdjangoコードとうまく連携します。order_byを実行し、通常のdjangoメソッドを使用してクエリセットを制限/スライスする方法に注目してください。

于 2021-02-25T19:41:05.427 に答える