django orm:select_lated,用假外键欺骗反向外键除了模型之外,会出现什么问题?

2024-05-16

我正在尝试学习如何使用 Django 的 ORM 进行更高级的查询,而不是使用原始 sql。

select_related进行连接以减少数据库命中,原则上它可以进行我手动执行的连接。

但有一个问题:它不使用反向外键关系来制作sql。对于我的架构来说,这是一个麻烦。我发现了一种看起来非常简单的解决方法,但我担心它会以我不理解的方式出现错误。

我使用的是旧版数据库,它是只读的,因此不受 ORM 管理,并且级联设置不会产生任何后果。我通过manage.py analysisdb为其表制作了模型,效果非常好;我有一个 6000 行的模型文件,只需要花十分钟就可以修复。

我所做的一个调整是一种欺骗select_related通过创建外键关系,实际上是反向 FK 关系。这意味着我的模型中有两个条目指向同一数据库列,这是主键(正确),现在也是外键。我利用了“新”专栏select_related.

我的查询的主表是 Service。它与许多其他表具有外键关系,并且与 select_lated 配合使用效果很好。

servrecid_1 列是我人为添加的。另外两列是两列真正的 FK;还有更多。

class Service(models.Model):
    servrecid = models.AutoField(db_column='ServRecID', primary_key=True)
    servrecid_1 = models.ForeignKey('RecServ', models.DO_NOTHING, to_field='servrecid',
                                    db_column='ServRecID')  # Field name made lowercase.

    visitrecordid = models.ForeignKey('Visit', models.DO_NOTHING, db_column='VisitRecordID', blank=True,
                                      null=True)  # Field name made lowercase.
    itemno = models.ForeignKey(Fees, models.DO_NOTHING, db_column='ItemNo', to_field='itemno')
    ...
    class Meta:
        managed = False  # same for all the models


class RecServ(models.Model):
    allocationid = models.AutoField(db_column='AllocationID', primary_key=True)  # Field name made lowercase.
    servrecid = models.ForeignKey('Service', models.DO_NOTHING, db_column='ServRecID')  # Field name made lowercase.
    receiptno = models.ForeignKey(Receipt, models.DO_NOTHING, db_column='ReceiptNo')  # Field name made lowercase.

(关系比我在上面的片段中显示的要多)

有了这个,我现在可以进行如下查询:

q = models.Service.objects.select_related('visitrecordid__servdoctor').select_related('visitrecordid__invoiceto') \
        .select_related('visitrecordid__patientno').select_related('itemno').select_related(
    'servrecid_1__receiptno').all()[:5]

它使用这些连接创建一个查询:

    ... FROM [SERVICE] INNER JOIN [REC_SERV] ON ([SERVICE].[ServRecID] = [REC_SERV].[ServRecID])
 INNER JOIN [RECEIPT] ON ([REC_SERV].[ReceiptNo] = [RECEIPT].[ReceiptNo]) 
LEFT OUTER JOIN [VISIT] ON ([SERVICE].[VisitRecordID] = [VISIT].[VisitRecordID]) 
LEFT OUTER JOIN [CM_PATIENT] ON ([VISIT].[PatientNo] = [CM_PATIENT].[PATIENT_ID]) 
LEFT OUTER JOIN [DOCTOR] ON ([VISIT].[ServDoctor] = [DOCTOR].[DoctorCode]) 
LEFT OUTER JOIN [INVOICETO] ON ([VISIT].[InvoiceTo] = [INVOICETO].[InvoiceTo]) 
INNER JOIN [FEES] ON ([SERVICE].[ItemNo] = [FEES].[ItemNo])

第一次加入只是因为我的 FK 错误而出现。 SQL 对我来说看起来很好,我想我已经解决了我的问题。

这实际上应该有效吗?两个表之间的相互外键关系现在会发生什么?


如果从 RecServ 到 Service 的关系是多对一的,您将在查询集中得到重复的条目。也就是说,如果你的Service条目将有 4 个相应的条目RecServ表中,您的查询集将包含此对象 4 次。

同样,如果你的RecServ表中没有条目Service, 相应的Service对象将从您的查询集中丢失,即使它存在。

对于强制性的一对一关系,外键条目采用哪种模型并不重要。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

django orm:select_lated,用假外键欺骗反向外键除了模型之外,会出现什么问题? 的相关文章

随机推荐

  • Node 不断恢复到旧版本

    每次我在控制台中重新启动 vagrant 时 它都会询问我的登录详细信息 然后说Now using node v7 10 0 npm v4 2 0 当我做run nvm install node I get v13 11 0 is alre
  • 为什么我收到“无法进行二进制日志记录”的信息。在我的 MySQL 服务器上?

    当我今天启动 MySQL 服务器并尝试使用以下命令进行一些更改时用于 MySQL 的 Toad http www quest com toad for mysql 我收到此消息 MySQL 数据库错误 无法进行二进制日志记录 消息 交易级别
  • Struts 1 到 Spring 迁移 - 策略

    我有一个legacy银行应用程序编码为Struts 1 JSP现在的要求是迁移后端 目前为 MVC to Springboot MVC 后续UI JSP 将迁移到angular Caveats 1 后端不是无状态的 2 会话对象中存储了大量
  • SQL 查询将文本数据存储在 Varbinary(max) 中

    有没有办法让 varbinary 在 SQL Server 中接受文本数据 这是我的情况 我有相当大量的 XML 我计划以 压缩 格式存储它们 这意味着 Varbinary 但是 当我进行调试时 我希望能够翻转配置开关并以纯文本形式存储 以
  • 具有多个谓词的 C++11 算法

    功能如std find if来自algorithmheader 确实很有用 但对我来说 一个严重的限制是我只能为每次调用使用 1 个谓词count if 例如给定一个像这样的容器std vector我想同时应用相同的迭代find if 多个
  • Python“非规范化”unicode 组合字符

    我正在寻找标准化 python 中的一些 unicode 文本 我想知道是否有一种简单的方法可以在 python 中获得组合 unicode 字符的 非规范化 形式 例如如果我有序列u o xaf i e latin small lette
  • 在 Mac OS X 上安装 libxml2 时出现问题

    我正在尝试在我的 Mac 操作系统 10 6 4 上安装 libxml2 我实际上正在尝试在 Python 中运行 Scrapy 脚本 这需要我安装 Twisted Zope 现在还需要安装 libxml2 我已经下载了最新版本 2 7 7
  • Facebook API - fql_query,无效会话

    我正在尝试使用 PHP 库查询 Facebook 我读到的内容不应该需要会话密钥 或者更确切地说 对于我的情况 它不应该需要会话密钥 但下面的代码给出了以下错误 Session密钥无效或不再有效 http wiki developers f
  • (Rails) Assert_Select 的烦人警告

    有谁知道如何让assert select在rake测试期间不输出所有那些讨厌的html警告 你知道 就像这样的东西 ignoring attempt to close body with div opened at byte 1036 li
  • 如何在 JPA 和 Hibernate 中将数据库生成的列值定义为只读字段?

    使用 MariaDB 10 2 可以定义日期时间的默认值 例如创建和最后修改 我应该如何将此列作为只读字段访问 因为这个值应该只在数据库的控制之下 并且不应该从代码中修改 但我想在代码中读取这个属性 这很简单 只需设置insertable
  • 如何使用 ffmpeg 将两个视频/音频流混合为一个

    我有两个视频 v1 flv 和 v2 flv 想要创建 v3 flv 其中包含来自 v1 flv 的视频流以及来自 v1 flv 和 v2 flv 的 混合 音频流 使用 ffmpeg 命令可以实现类似的操作吗 谢谢 我认为使用 ffmpe
  • Rails/Nginx 中的超时——最佳实践

    我正在开发一个应该在 Nginx 服务器上运行的 Rails 应用程序 根据输入 应用程序可能需要很长时间来处理请求 或者在出现错误时挂起 因此我想防止进程永远运行 除了确保客户端收到超时信号的 Nginx 配置之外 我想我可能仍然需要确保
  • Windows 2000 说超时不是命令或批处理文件

    我只是在摆弄 CMD 并制作动画 ASCII 艺术 我一直在尝试在 Windows 2000 笔记本电脑上使用 超时 命令 但是每次我尝试这样做时 它只是说它不是内部或外部命令或批处理文件 这是一台运行 Windows 2000 的旧东芝
  • 使用 attr_accessor 动态创建类属性

    在Ruby中 有没有办法动态地将实例变量添加到类中 例如 class MyClass def initialize create attribute name end def create attribute name attr acces
  • MSMQ接收和删除

    是否有任何选项可以在读取消息后将其从 MSMQ 中删除 比如 接收 删除可以作为原子操作运行吗 听起来您想查看下一条消息 然后在处理完成后接收它 Message message Queue Peek Queue ReceiveById me
  • 联合数据类型上的条件数据类型

    假设您有以下类型 type Foo prop1 foo prop2 null type Bar prop1 bar prop2 number type FooOrBar Foo Bar 是否可以使用条件类型重写上述代码 我已经尝试过以下方法
  • 在 Visual Studio 2017 的现有实例中打开文件

    我曾经能够在 VS 的现有实例中打开文件 devenv exe had a dde为此切换 但在 VS2017 中 它会在新实例中打开文件 而不是在已经运行的实例中 例如对于 json 文件 我的注册表有一个密钥HKEY CLASSES R
  • Rangy:插入符号下的单词(再次)

    我正在尝试创建一个预输入代码以添加到 wysihtml5 富文本编辑器 基本上 我需要能够插入人员 标签引用 例如 Twitter Github Facebook 我发现一些人试图实现同样的事情的代码 http jsfiddle net A
  • 无法指向 Jenkins 主机上 ~/.ssh 中的 ssh 密钥

    我已经安装了 SSH 代理插件来使用 SSH 身份验证拉取 Git 存储库 我想使用位于系统文件中的 SSH 密钥 来自 Jenkins master ssh选项 这是从官方插件页面截取的屏幕截图 不幸的是我没有看到这个选项 我只能选择 直
  • django orm:select_lated,用假外键欺骗反向外键除了模型之外,会出现什么问题?

    我正在尝试学习如何使用 Django 的 ORM 进行更高级的查询 而不是使用原始 sql select related进行连接以减少数据库命中 原则上它可以进行我手动执行的连接 但有一个问题 它不使用反向外键关系来制作sql 对于我的架构