【问题标题】:Django - Existing DB Views and Foreign KeysDjango - 现有的数据库视图和外键
【发布时间】:2019-11-26 11:59:20
【问题描述】:

我有一个简单的数据库视图,它从位于同一 MSSQL 服务器上的其他数据库表中进行选择,最终将收集到的信息作为下拉列表提供给用户。

到目前为止,我已经使用 inspectdb 添加了模型:

class AutPricePlanView(models.Model):
      priceplan_name = models.CharField(db_column='PricePlan', max_length=50, blank=True, unique=True)

            class Meta:
                managed = False  # Created from a view. Don't remove.
                db_table = 'AUT_PricePlanView'

我还有第二个现有的(Django Native)模型,我想将视图中的值用于下拉字段(以保持所有内容同步):

class PricePlanDownload(models.Model):
    requesting_user = models.CharField(blank=True, default=None, max_length=50, null=True)
    requested_at = models.DateTimeField(auto_now_add=True)
    document = models.FileField(upload_to='documents/price_plan_uploads/%Y/%m/%d', blank=True)
    priceplan = models.ForeignKey(AutPricePlanView, null=True, on_delete=models.DO_NOTHING)

Makemigrations 工作正常,但是当我尝试实际迁移时,我遇到了以下问题:(缩短了一点) django.db.utils.ProgrammingError: ('42000', "[42000] [FreeTDS][SQL Server]外键引用不是用户表的对象'AUT_PricePlanView'。(1768) (SQLExecDirectW)")

如果有人有想法或解决方法,我将非常感激,因为我无法弄清楚这与“用户”表有什么关系......

【问题讨论】:

    标签: django django-models


    【解决方案1】:

    由于视图实际上不是表,因此您无法设置外键约束。由于ForeignKey 的默认db_constraint 值为True,Django 在执行迁移时尝试设置外键约束。这就是迁移失败的原因。

    因此,您可以关闭db_constraint 选项。您可以删除现有的迁移文件,然后重新创建迁移文件。然后,迁移将成功,您可以保持一切同步。

    class PricePlanDownload(models.Model):
        ... other fields ...
        priceplan = models.ForeignKey(AutPricePlanView, null=True, on_delete=models.DO_NOTHING, db_constraint=False)
    

    专业提示:您可以使用 python manage.py sqlmigrate <appname> <migration number> 来查看迁移的 SQL,例如 python manage.py sqlmigrate yourapp 0002


    更新:您可以定义__str__ 以在下拉菜单中显示正确的值。

    class AutPricePlanView(models.Model):
        priceplan_name = models.CharField(db_column='PricePlan', max_length=50, blank=True, unique=True, primary_key=True)  
        # null=False by default. See https://github.com/django/django/blob/master/django/db/models/fields/__init__.py#L132
    
        def __str__(self):
            return self.priceplan_name
    
        class Meta:
            managed = False  # Created from a view. Don't remove.
            db_table = 'AUT_PricePlanView'
    

    【讨论】:

    • 谢谢!我还需要设置“null=False,primary_key=True”,否则视图会在不存在的“id”列上给出错误。现在奇怪的是下拉菜单不仅显示值(=***),还显示“AutPricePlan View object(***)”??
    • @zeitghaist 我更新了我的答案。您可以在AutPricePlanView 处定义__str__ 函数。无论如何,因为null默认是False,你可以安全地删除null=False:)
    • 像魅力一样工作,非常感谢!!! (想对您的答案表示赞同,但我错过了声誉)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-02-15
    • 2018-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-15
    • 1970-01-01
    相关资源
    最近更新 更多