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, указывающий на представление, и позволить 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
смела DatabaseCreation.sql_for_inline_foreign_key_references в django_mssql creation.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)
сгенерированный 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 --
);
это связано с взломом django_mssql, поэтому я буду продолжать пытаться, возможно, подключаясь к Джанго.децибел.внутренний.сигналы.connection_created сигнал будет работать...
2 ответов
если вы устанавливаете managed=False
(Django docs) в class, Django не будет создавать таблицу при запуске syncdb.
class AssessmentLocation(models.Model):
name = models.CharField(max_length=150)
org = models.ForeignKey(OrgCode)
class Meta:
managed = False
у Джанго есть крюк, чтобы предоставить исходные данные sql. Мы можем (АБ?)используйте это, чтобы заставить 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 для создания таблицы. В противном случае, я думаю, этот подход сработает.