将 go-pg 查询转换为普通 sql

convert go-pg query into plain sql

是否可以转换 go-pg 查询

err = db.Model(story).
        Relation("Author").
        Where("story.id = ?", story1.Id).
        Select()

变成普通的SQL?

这对调试很有帮助。所以我可以将这个普通的 SQL 查询和 运行 作为字符串复制到 psql 客户端中。 可能有某种包装?

这在项目的 wiki 中列出:

How to view queries this library generates?

如何查看此库生成的查询?

您可以像这样设置查询记录器:

type dbLogger struct { }

func (d dbLogger) BeforeQuery(c context.Context, q *pg.QueryEvent) (context.Context, error) {
    return c, nil
}

func (d dbLogger) AfterQuery(c context.Context, q *pg.QueryEvent) (context.Context, error) {
    fmt.Println(q.FormattedQuery())
    return c, nil
}

db := pg.Connect(&pg.Options{...})
db.AddQueryHook(dbLogger{})
 //db your *pg.DB
// q your  *orm.Query = db.Model(&yourModel).



 qq := pg.QueryEvent{
            DB:        db,
            Model:     q.TableModel(),
            Query:     q,
        }
 fmt.Println(qq.FormattedQuery())

所以在你的情况下

q:= db.Model(story).
        Relation("Author").
        Where("story.id = ?", story1.Id)
fmt.Println("running SQL:")
qq := pg.QueryEvent{
                DB:        db,
                Model:     q.TableModel(),
                Query:     q,
            }
fmt.Println(qq.FormattedQuery()) 
q.Select()

问题:自 v10 以来,没有默认从 ORM 解析为 RAW sql。


好吧,我想已经太晚了。也许有人(比如我)会在 2021 年遇到这个问题。您可以通过一些步骤解决这个问题:

  • [x] 阅读文档。
  • [x] 检查所有结构。
  • [x]实现所有方法。

解决问题


这个解决方案是从这个 issue“分叉”出来的,但我会逐步解释它。 首先我们需要阅读一些 source code 的 go-pg hook。 正如我之前所说:我们需要检查此文档中的所有结构。但我们很幸运。只有 1 个结构!

// QueryEvent ...
type QueryEvent struct {
    StartTime  time.Time
    DB         orm.DB
    Model      interface{}
    Query      interface{}
    Params     []interface{}
    fmtedQuery []byte
    Result     Result
    Err        error

    Stash map[interface{}]interface{}
}

我们真的不需要完全实现这个结构。 但是当你使用 db.AddQueryHook() (其中 db 是我们的数据库连接上的引用,AddQueryHook() 是方法)AddQueryHook() 等待你这个 interface:

type QueryHook interface {
    BeforeQuery(context.Context, *QueryEvent) (context.Context, error)
    AfterQuery(context.Context, *QueryEvent) error
}

所以,我们已经阅读了 DOC,检查了结构。接下来是什么?答案很简单:

  • 实现所有方法。

TBH,我认为这比实际更难。 要实现它,您只需要创建 2 个当前(新的空)结构的方法来实现上述方法的功能,如下所示:

  1. 正在创建空结构 type dbLogger struct{}
  2. 从文档中添加方法:
func (d dbLogger) BeforeQuery(c context.Context, q *pg.QueryEvent) (context.Context, error) {
    return c, nil
}

func (d dbLogger) AfterQuery(c context.Context, q *pg.QueryEvent) error {
    fq, _ := q.FormattedQuery()
    fmt.Println(string(fq))
    return nil
}

我希望这对遇到这个问题的每个人都有帮助。

我刚刚从 go-pg v7 升级到 v10,遇到了一个问题,我用来获取 RAW SQL 的 Query.AppendFormat() 已被删除。

在使用此 post 中的评论作为灵感后,我使用下面的代码成功提取了它


import (
    "github.com/go-pg/pg/v10/orm"
)

func QueryToString(q *orm.Query) string {
    value, _ := q.AppendQuery(orm.NewFormatter(), nil)

    return string(value)
}

希望这对未来的观众有所帮助