首页 > 后端开发 > Golang > 正文

包含软删除行的 Join 子句

PHPz
发布: 2024-02-08 20:42:20
转载
745人浏览过

包含软删除行的 join 子句

问题内容

我在使用 go-pg orm 生成正确的连接选择查询时遇到问题,其中一个表记录可以被软删除,而其他 2 个表记录则不能。

数据库表:

pipeline_instances
instance_id int
pipeline_id int
event_id int
pipeline_triggers
id int
pipeline_id int
deleted_at timestamp
pipeline_trigger_events
event_id int
trigger_id int

go-pg 型号:

type pipelinetriggerevent struct {
    tablename        struct{}          `pg:"pipeline_trigger_events,alias:pte"`
    trigger          *pipelinetrigger  `pg:"rel:has-one,join_fk:id"`
    pipelineinstance *pipelineinstance `pg:"rel:has-one,join_fk:event_id"`
    *triggerevent
}

type pipelinetrigger struct {
    tablename struct{} `pg:"pipeline_triggers,alias:pt"`
    *trigger 
}

type pipelineinstance struct {
    tablename struct{} `pg:"pipeline_pipeline_instances,alias:ppi"`
    *pipelineinstance
}
登录后复制

我尝试生成的查询:

select 
  pte.*, trigger.*, pipeline_instance.*
from 
  pipeline_trigger_events as pte 
  left join pipeline_triggers as trigger on (trigger.id = pte.trigger_id) 
  left join pipeline_pipeline_instances as pipeline_instance on pipeline_instance.event_id = pte.event_id and trigger.pipeline_id = pipeline_instance.pipeline_id
登录后复制

由 go-pg orm 生成的查询:

select 
  pte.*, trigger.*, pipeline_instance.*
from 
  pipeline_trigger_events as pte 
  left join pipeline_triggers as trigger on (trigger.id = pte.trigger_id) 
      and trigger.deleted_at is null -- this is the unwanted line.
  left join pipeline_pipeline_instances as pipeline_instance on pipeline_instance.event_id = pte.event_id and trigger.pipeline_id = pipeline_instance.pipeline_id
登录后复制
var triggerevents []pipelinetriggerevent
q := db.model(&triggerevents).
        column("pte.*").
        relation("trigger").
        relation("pipelineinstance", func(q *orm.query) (*orm.query, error) {
            q = q.join(" and trigger.pipeline_id = pipeline_instance.pipeline_id")
            return q, nil
        })
登录后复制

在上述所有3个表/模型中,只有pipeline_triggers表具有用于软删除的deleted_at列。我的要求是将软删除的 pipeline_triggers 行也包含在结果集中。但是 go-pg orm 会自动在 join 子句中添加 trigger.deleted_at is null 条件。如何删除此条件并获取所有行,包括软删除的行。

我尝试使用 allwithdeleted 函数,但它适用于主模型,即 pipeline_trigger_events (并且该表无论如何都没有deleted_at 列),而不适用于 pipeline_triggers ,因此失败并出现此错误: pg: model=pipelinetriggerevent 不支持软删除


正确答案


稍微浏览了一下 pg-go 的代码后,我不知道是否支持您想要做的事情。为了确定这一点,您可能需要在调试器中单步执行下面的代码。

当为连接构建查询时,它具有以下部分:

https://github.com/go -pg/pg/blob/c9ee578a38d6866649072df18a3dbb36ff369747/orm/join.go#l283

if issoftdelete {
        b = append(b, " and "...)
        b = j.appendalias(b)
        b = j.appendsoftdelete(b, q.flags)
    }
登录后复制

j.appendalias(b) 行调用以下 appendalias() 函数: https://github.com/go-pg/ pg/blob/c9ee578a38d6866649072df18a3dbb36ff369747/orm/join.go#l200

func appendalias(b []byte, j *join) []byte {
    if j.hasparent() {
        b = appendalias(b, j.parent)
        b = append(b, "__"...)
    }
    b = append(b, j.rel.field.sqlname...)
    return b
}
登录后复制

由于连接都具有一对一的父关系,因此会为所有表添加它: https://github.com/go-pg/ pg/blob/c9ee578a38d6866649072df18a3dbb36ff369747/orm/join.go#l153

func (j *join) hasparent() bool {
    if j.parent != nil {
        switch j.parent.rel.type {
        case hasonerelation, belongstorelation:
            return true
        }
    }
    return false
}
登录后复制

我认为解决这个问题的方法是只为父关系调用 appendalias() 而不是其他两个,但看起来 pg-go 不支持这一点。

为此,您只需调用 pg.query() 或 pg.querywithcontext() 并传入上面包含的 sql 语句即可。

还值得一提的是,pg-go/pg 处于维护模式,因此他们不太可能支持这一点。根据这个项目在 pg-go 中的根深蒂固程度,您可能会考虑使用 bun 正在积极开发中。

附录

这是上面第一个代码片段中调用的 appendsoftdelete() 函数:

https://github.com/go -pg/pg/blob/c9ee578a38d6866649072df18a3dbb36ff369747/orm/join.go#l189

func (j *join) appendSoftDelete(b []byte, flags queryFlag) []byte {
    b = append(b, '.')
    b = append(b, j.JoinModel.Table().SoftDeleteField.Column...)
    if hasFlag(flags, deletedFlag) {
        b = append(b, " IS NOT NULL"...)
    } else {
        b = append(b, " IS NULL"...)
    }
    return b
}
登录后复制

以上就是包含软删除行的 Join 子句的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:stackoverflow网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号