2011-11-08 27 views
7

私はデータベースビューによってバックアップされたモデルを持っています。Django - データベースの外部キー制約の作成を防止する方法

class OrgCode(models.Model): 
    org_code    = models.CharField(db_column=u'code',max_length=15) 
    org_description   = models.CharField(max_length=250) 
    org_level_num   = models.IntegerField() 

    class Meta: 
     db_table = u'view_FSS_ORG_PROFILE' 

私は、外部キー制約は、ビューを参照作成することはできませんので、私はsyncdbの実行を実行することはできません別のモデル

class AssessmentLocation(models.Model): 
    name    = models.CharField(max_length=150) 
    org     = models.ForeignKey(OrgCode) 

でこれを参照する必要があります。

u"Foreign key 'FK__main_asse__org__1D114BD1' 
references object 'view_FSS_ORG_PROFILE' 
which is not a user table.", None, 0, -214 
7217900), None) 
Command: 
CREATE TABLE [main_assessmentlocation] (
    [id] int IDENTITY (1, 1) NOT NULL PRIMARY KEY, 
    [name] nvarchar(150) NOT NULL, 
    [org] int NOT NULL REFERENCES [view_FSS_ORG_PROFILE] ([id]), 
) 

回避策は、メタ取ることです:ビューにDB_Tableのポインティングをし、同期DBはOrgCodeテーブルを作成してみましょう、そしてメタを置く:バックsyncdbの実行の後でのDB_Table。

特定のモデルまたはフィールドの外部キー制約の作成を防止する方法はありますか?

更新:それは、ビュー

class OrgCode(models.Model): 
    org_code    = models.CharField(max_length=15) 
    org_description   = models.CharField(max_length=250) 

    @staticmethod 
    def is_backend_view(): 
     return True 

だ示す関連モデルに静的メソッドを追加django_mssql creation.pyにDatabaseCreation.sql_for_inline_foreign_key_referencesをオーバーライド:

def sql_for_inline_foreign_key_references(self, field, known_models, style): 
    try: 
     field.rel.to.is_backend_view() 
     return "", False 
    except: 
     return super(DatabaseCreation,self).sql_for_inline_foreign_key_references(field, known_models, style)  

から生成されるSQL syncdbは、制約を除外します。

CREATE TABLE [main_assessmentlocation] (
    [id] int IDENTITY (1, 1) NOT NULL PRIMARY KEY, 
    [name] nvarchar(150) NOT NULL, 
    [org] int, -- NO FK CONSTRAINT ANYMORE -- 
); 
012あなたが設定した場合

それはので、私は多分動作しますdjango.db.backends.signals.connection_created信号に引っ掛け、挑戦を続けるつもりだdjango_mssqlハッキング関与しない...

答えて

10

django開発バージョンは、ForeignKeyのモデルフィールドにはdb_constraintフィールドがあります。docsです。

+0

ありがとう!それが私が必要としていたものですが、今はリリースに着陸するのを待たなければなりません。ハックを取り除くことができます。 –

+1

バージョン1.6以降、 'db_constraint'は安全に使用できます –

4

モデルの中managed=FalseDjango docsMetaクラスでは、syncdbの実行時にDjangoはテーブルを作成しません。

class AssessmentLocation(models.Model): 
    name = models.CharField(max_length=150) 
    org = models.ForeignKey(OrgCode) 

    class Meta: 
     managed = False 

Djangoはprovide initial sql dataにフックを持っています。これを使って、syncdbを実行した直後にDjangoにテーブルを作成させることができます。

create table文を含む、ファイルmyapp/sql/assessmentlocation.sqlを作成します。

CREATE TABLE [main_assessmentlocation] (
    [id] int IDENTITY (1, 1) NOT NULL PRIMARY KEY, 
    [name] nvarchar(150) NOT NULL, 
    [org] int, -- NO FK CONSTRAINT ANYMORE -- 
); 

あなたはAssessmentLocationモデルへの外部キーを持つ他のモデルを持っている場合Djangoは実行する前に、外部キー制約を適用しようとすると、あなたが問題を抱えていることカスタムSQLは、テーブルを作成する。さもなければ、私はこのアプローチがうまくいくと思います。

+0

ありがとうございます!私はこれを見て、それは動作します。ビューベースの関連オブジェクトモデルは、他の開発者が使用するために構築しているフレームワークの一部です。私は、syncdbモデルの作成と標準のdjangoのドキュメントから逸脱しないようにしています。 –

関連する問題