首页 > 解决方案 > 带有 db_constraint= False 和 postresql 的外键:外键似乎引用了错误的父字段

问题描述

我正在准备用于分析工具 (Microsof Power BI) 的表格。显示表格之间的关系以帮助构建报告会很有帮助。但是,我不想使用带约束的外键,因为数据更新和完整性检查的方法不需要约束,它实际上会妨碍。此代码支持的一些备用后端用于不提供真正外键的云数据库。我提到这一点是因为这意味着我正在尝试定义这样的外键字段:

 order_guid = models.ForeignKey("Dear_sales_header",to_field="order_guid",db_constraint=False,on_delete=models.DO_NOTHING)

迁移文件有这个:

  operations = [
        migrations.AlterField(
            model_name='sales_fact',
            name='order_guid',
            field=models.ForeignKey(db_constraint=False, on_delete=django.db.models.deletion.DO_NOTHING, to='dear_zoho_analytics.Dear_sales_header', to_field='order_guid'),
        ),
    ]

此表被路由到不同的数据库

python manage.py migrate  --database=dear_analytics

确实表明应用了迁移文件(它是 0026)

  Applying dear_zoho_analytics.0026_auto_20210217_2245... OK

但是当我在我的 IDE 中检查 postgresql 模式时,sales_fact 中的列被重命名为

order_guid_id

所以看起来我做错了什么,因为这似乎引用了“父表”dear_sales_header 的 id 字段,但我需要它来引用唯一但不是主键的 Dear_sales_header.order_guid。

模型的部分摘录:

class AnalyticsTable:
    # a dummy class used to mark the DearAnalytics tables. Creating a subclass of models.Model breaks things in the ORM such as bulk update
    pass


class Sales_fact(models.Model, AnalyticsTable):
    analytics_table_name = "sales_fact"
    #order_guid = models.CharField(max_length=1024, null=True, blank=True, help_text="")
    order_guid = models.ForeignKey("Dear_sales_header",to_field="order_guid",db_constraint=False,on_delete=models.DO_NOTHING)
    source_dear = models.CharField(max_length=1024, null=True, blank=True,
                                   help_text="Link to Dear instance which is the source of the data")


class Dear_sales_header(models.Model, AnalyticsTable):
    analytics_table_name = "dear_sales_header"
    source_dear = models.CharField(max_length=1024, null=True, blank=True,
                                   help_text="Link to Dear instance which is the source of the data")
    order_guid = models.CharField(max_length=1024, unique=True, help_text="")

    global_sale_status = models.CharField(max_length=1024, null=True, blank=True, help_text="SO Header status")
    order_status = models.CharField(max_length=1024, null=True, blank=True, help_text="")

标签: djangodjango-models

解决方案


Django 将后缀 _id 添加到文档ForeignKey中的名称

在幕后,Django 将“_id”附加到字段名称以创建其数据库列名称。

如果您希望名称不包含任何添加,则应设置db_column

用于此字段的数据库列的名称。如果没有给出,Django 将使用该字段的名称。

order_guid = models.ForeignKey(
    "Dear_sales_header", to_field="order_guid", db_constraint=False, 
    db_column='order_guid',on_delete=models.DO_NOTHING
)

在 MRE 中,我无法重现任何不良行为,Django 确实正确映射ForeignKey到您设置的列,同时db_constraint=True正确设置广告右后约束并将其作为后向操作丢弃

    constraint testbench_sales_fact_order_guid_f2dab1c5_fk_testbench
        references testbench_dear_sales_header (order_guid)
        deferrable initially deferred

推荐阅读