J'ai un problème pour générer une requête de sélection de jointure correcte à l'aide de go-pg
orm, l'un des enregistrements de la table peut être supprimé de manière logicielle mais les 2 autres enregistrements de la table ne le peuvent pas.
Tableau de base de données :
pipeline_instances |
---|
instance_id int |
pipeline_id int |
event_id int |
pipeline_triggers |
---|
id int |
pipeline_id int |
horodatage supprimé_at |
pipeline_trigger_events |
---|
event_id int |
trigger_id int |
go-pg Modèle :
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 }
La requête que j'essaie de générer :
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
Requête générée par 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 })
Sur les 3 tables/modèles mentionnés ci-dessus, seule la table pipeline_triggers a une colonne deleted_at
pour les suppressions logicielles. Mon exigence est d'inclure également les lignes pipeline_triggers supprimées de manière logicielle dans l'ensemble de résultats. Mais deleted_at
列。我的要求是将软删除的 pipeline_triggers 行也包含在结果集中。但是 go-pg
orm 会自动在 join
子句中添加 trigger.deleted_at is null
orm ajoutera automatiquement la condition trigger.deleted_at is null
dans la clause join
. Comment puis-je supprimer cette condition et obtenir toutes les lignes, y compris les lignes supprimées de manière logicielle.
J'ai essayé d'utiliser la fonction allwithdeleted, mais cela fonctionne pour le modèle principal, qui est pipeline_trigger_events (et la table n'a pas de colonne delete_at de toute façon), mais pas pour pipeline_triggers
, donc elle échoue avec cette erreur :
pg: model=pipelinetriggerevent 不支持软删除
Après avoir parcouru un peu le code de pg-go, je ne sais pas si ce que vous voulez faire est pris en charge. Pour déterminer cela, vous devrez peut-être parcourir le code ci-dessous dans le débogueur.
Lors de la création d'une requête pour une jointure, elle comprend les parties suivantes :
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()
Fonction :
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 }
Étant donné que les jointures ont toutes une relation parent un à un, elle est ajoutée pour toutes les tables : 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 }
Je pensais que la solution serait d'appeler appendalias()
uniquement pour la relation parentale et pas pour les deux autres, mais il semble que pg-go ne supporte pas cela.
Pour ce faire, il vous suffit d'appeler pg.query()
或 pg.querywithcontext()
et de transmettre l'instruction SQL contenue ci-dessus.
Il convient également de mentionner que pg-go/pg est en mode maintenance, il est donc peu probable qu'ils le prennent en charge. En fonction de l'enracinement de ce projet dans pg-go, vous pourriez envisager d'utiliser bun qui est en cours de développement actif.
Annexe
Voici la fonction appendsoftdelete()
appelée dans le premier extrait de code ci-dessus :
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 }
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!