Heim  >  Artikel  >  Backend-Entwicklung  >  Join-Klausel mit vorläufig gelöschten Zeilen

Join-Klausel mit vorläufig gelöschten Zeilen

PHPz
PHPznach vorne
2024-02-08 20:42:20719Durchsuche

包含软删除行的 Join 子句

Frageninhalt

Ich habe ein Problem beim Generieren einer korrekten Join-Select-Abfrage mit go-pg orm. Einer der Tabellendatensätze kann vorläufig gelöscht werden, die anderen beiden Tabellendatensätze jedoch nicht.

Datenbanktabelle:

pipeline_instances
instance_id int
pipeline_id int
event_id int
pipeline_triggers
id int
pipeline_id int
gelöscht_zum Zeitstempel
pipeline_trigger_events
event_id int
trigger_id int

go-pg Modell:

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
}

Die Abfrage, die ich zu generieren versuche:

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

Von go-pg orm generierte Abfrage:

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
        })

Von allen drei oben genannten Tabellen/Modellen verfügt nur die Tabelle „pipeline_triggers“ über die Spalte „deleted_at“ für vorläufige Löschvorgänge. Meine Anforderung besteht darin, auch die vorläufig gelöschten Pipeline_triggers-Zeilen in die Ergebnismenge aufzunehmen. Aber deleted_at列。我的要求是将软删除的 pipeline_triggers 行也包含在结果集中。但是 go-pg orm 会自动在 join 子句中添加 trigger.deleted_at is null orm fügt der join-Klausel automatisch die Bedingung trigger.deleted_at is null hinzu. Wie kann ich diese Bedingung entfernen und alle Zeilen einschließlich der vorläufig gelöschten Zeilen abrufen?

Ich habe versucht, die Funktion „allwithdeleted“ zu verwenden, aber sie funktioniert für das Hauptmodell „pipeline_trigger_events“ (und die Tabelle hat ohnehin keine Spalte „deled_at“), aber nicht für pipeline_triggers, daher schlägt sie mit folgendem Fehler fehl: pg: model=pipelinetriggerevent 不支持软删除


Richtige Antwort


Nachdem ich den Code von pg-go ein wenig durchgesehen habe, weiß ich nicht, ob das, was Sie tun möchten, unterstützt wird. Um dies festzustellen, müssen Sie möglicherweise den folgenden Code im Debugger durchgehen.

Beim Erstellen einer Abfrage für einen Join besteht diese aus den folgenden Teilen:

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() Funktion: 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
}

Da Joins alle eine Eins-zu-eins-Elternbeziehung haben, wird sie für alle Tabellen hinzugefügt: 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
}

Ich dachte, die Lösung wäre, appendalias() nur für die Elternbeziehung aufzurufen und nicht für die anderen beiden, aber es sieht so aus, als ob pg-go dies nicht unterstützt.

Dazu rufen Sie einfach pg.query()pg.querywithcontext() auf und übergeben die oben enthaltene SQL-Anweisung.

Erwähnenswert ist auch, dass sich pg-go/pg im Wartungsmodus befindet, daher ist es unwahrscheinlich, dass sie dies unterstützen. Je nachdem, wie fest dieses Projekt in pg-go verankert ist, könnten Sie die Verwendung von bun in Betracht ziehen, das sich in der aktiven Entwicklung befindet.

Anhang

Dies ist die appendsoftdelete()-Funktion, die im ersten Codeausschnitt oben aufgerufen wurde:

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
}

Das obige ist der detaillierte Inhalt vonJoin-Klausel mit vorläufig gelöschten Zeilen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen