我有一个由数据库视图支持的模型。
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,让sync db创建OrgCode表,然后将meta:db_table放回syncdb之后。
有没有办法阻止为某些模型或字段创建外键约束?
更新:我在相关模型中添加了一个静态方法,表明它是一个视图
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)
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.backends.signals.connection_created信号将起作用...
答案 0 :(得分:14)
django开发版具有[{1}}模型字段的db_constraint
字段 - docs。
答案 1 :(得分:4)
如果在模型的managed=False
类中设置Meta
(Django docs),Django将不会在运行syncdb时创建表。
class AssessmentLocation(models.Model):
name = models.CharField(max_length=150)
org = models.ForeignKey(OrgCode)
class Meta:
managed = False
Django有provide initial sql data的钩子。我们可以(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
模型的外键,则在执行自定义sql以创建表之前,如果Django尝试应用外键约束,则可能会出现问题。否则,我认为这种方法会起作用。