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'

我需要在另一个模型中引用这个

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

我不能运行syncdb,因为不能在引用视图时创建外键约束。

 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]),
)

解决方法是取出指向视图的Meta:db_table,让syncdb创建OrgCode表,然后在syncdb之后放回Meta: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

则覆盖DatabaseCreation。Sql_for_inline_foreign_key_references in django_mssql create .py:

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)    

syncdb生成的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 --
);

它确实涉及到破解django_mssql,所以我将继续尝试,也许挂钩到django.db.backend .signals。Connection_created信号将工作

django开发版有一个db_constraint字段用于ForeignKey模型字段- docs.

如果你在模型的Meta类中设置了managed=False (Django docs),当你运行syncdb时,Django将不会创建表。

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

Django有一个钩子来提供初始sql数据。我们可以(ab?)使用这个命令让Django在运行syncdb后立即创建表。

创建文件myapp/sql/assessmentlocation.sql,包含Create table语句:

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创建表之前尝试应用外键约束,你可能会遇到问题。否则,我认为这种方法是可行的。

相关内容

  • 没有找到相关文章

最新更新