2009-10-26 8 views
14

私はエンジニアリング会社向けのWebアプリケーションを作成しています(警告:私は趣味のプログラマです)、この問題を解決するまでDjangoを使用する予定でした。自然に使いたいモデルには、複数列の主キーがあります。 http://code.djangoproject.com/ticket/373で、私はDjangoを使用することはできません。少なくとも、リリースされたバージョンではありません。他のWebフレームワーク(Pythonベースのみ)を使用するか、モデルの変更を提案することでDjangoの制限に対応できるように、回避策を教えてもらえますか?私はこれをDjangoを学ぶ機会として使うことを望んでいたので、後者を本当に望んでいます。Djangoなどのコンポジットプライマリキー

例: 表1には、主キーを構成する必要がある2つのフィールドとしてpart_numberとpart_revisionがあります。 P/Nは複数のリビジョンに存在できますが、P/N + revは一意です。

表2は、主キーとしてpart_number、part_revisionおよびdimension_numberを持っています。特定のリビジョンのP/Nにはいくつかの次元がありますが、それぞれ固有のものです。また、この場合、P/N + revは表1のForeignKeyでなければなりません。

答えて

19

回避策は、主キー列として代理キー(自動インクリメント列)を作成し、ドメイン複合キーに一意のインデックスを配置することです。

外部キーは、サロゲート主キー列を参照します。

+1

1 - それを私にビート。 –

23

通常のプライマリキーを追加して、part_numberpart_revisionunique_togetherと指定するのはなぜですか?

これは本質的にミッチウィートが言ったことをするジャンゴー語(ジャンゴン?)方法です。

+0

うわー!これは実際には最高のソリューションです! –

+1

Pythonicに対応したDjangonic :) – ajay

14

サロゲートキーの使用を強くお勧めします。それは "Djangoesque"ではないからです。 part_numberを含む複合キーを使用するとします。後で、あなたの会社がそのフィールドのフォーマット(したがって値)を変更することを決定したらどうなりますか?または一般的な言葉で言えば、どの分野ですか?主キーの変更に対処する必要はありません。 「本当の」値からなるコンポジットキーを使用する際にどのようなメリットがあるのか​​分かりませんが、それは面倒なことではないと思います。意味のない、自動インクリメントされたキーを使用してください(おそらく複合キーは役に立たなくなります)。

+4

これはたくさん変更する必要があります。サロゲートがより良いアイデアである理由の良い記事は次のとおりです。http://www.agiledata.org/essays/keys.html – cethegeek

+0

ソフトウェア産業の大きな問題は、誰もが問題の大きな問題を解決しようとしていることです。一方、もし私が構造体が変更されているかどうかにかかわらず、Djangoをあらかじめ定義されたデータセットに適用しようとしているとすればどうでしょうか?もっと重要なことは、これがDjango自身のユースケースの1つであることです。つまり、「デッドラインを持つ完璧主義者のためのフレームワーク」です。 –

2

SQLAlchemyは複合主キーと外部キーをサポートしているので、SQLAlchemyベースのフレームワーク(PylonsとWerkzeugが思い浮かぶ)はあなたのニーズに合っているはずです。しかし、サロゲートプライマリキーは使いやすく、とにかくサポートされています。

0

あなただけのユニークな混合フィールドをしたい場合:

class MyTable(models.Model): 
    class Meta: 
     unique_together = (('key1', 'key2'),) 

    key1 = models.IntegerField() 
    key2 = models.IntegerField() 

をしかし、あなたはユニーク一緒に、列の1たい場合は、コードの下に似た主要試みること:

class MyTable(models.Model): 
    class Meta: 
     unique_together = (('key1', 'key2'),) 

    key1 = models.IntegerField(primary_key=True) 
    key2 = models.IntegerField()