问题内容
我在使用 go-pg orm 生成正确的连接选择查询时遇到问题,其中一个表记录可以被软删除,而其他 2 个表记录则不能。
数据库表:
pipeline_instancesinstance_id intpipeline_id intevent_id int
pipeline_triggersid intpipeline_id intdeleted_at timestamp
pipeline_trigger_eventsevent_id inttrigger_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 []pipelinetriggereventq := 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 子句的详细内容,更多请关注【创想鸟】其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。
发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2485281.html