首頁  >  文章  >  後端開發  >  包含軟刪除行的 Join 子句

包含軟刪除行的 Join 子句

PHPz
PHPz轉載
2024-02-08 20:42:20719瀏覽

包含软删除行的 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中文網其他相關文章!

陳述:
本文轉載於:stackoverflow.com。如有侵權,請聯絡admin@php.cn刪除