简体   繁体   English

在同一函数中对 Postgres 的多个查询

[英]Multiple queries to Postgres within the same function

I'm new to Go, so sorry for the silly question in advance!我是Go新手,很抱歉提前提出愚蠢的问题!

I'm using Gin framework and want to make multiple queries to the database within the same handler ( database/sql + lib/pq )我正在使用 Gin 框架并希望在同一个处理程序中对数据库进行多个查询( database/sql + lib/pq

userIds := []int{}
bookIds := []int{}
var id int

/* Handling first query here */
rows, err := pgClient.Query(getUserIdsQuery)
defer rows.Close()
if err != nil {
    return
}
for rows.Next() {
    err := rows.Scan(&id)
    if err != nil {
        return
    }
    userIds = append(userIds, id)
}

/* Handling second query here */
rows, err = pgClient.Query(getBookIdsQuery)
defer rows.Close()
if err != nil {
    return
}
for rows.Next() {
    err := rows.Scan(&id)
    if err != nil {
        return
    }
    bookIds = append(bookIds, id)
}

I have a couple of questions regarding this code (any improvements and best practices would be appreciated)我对此代码有几个问题(任何改进和最佳实践将不胜感激)

  1. Does Go properly handle defer rows.Close() in such a case?在这种情况下,Go 是否正确处理defer rows.Close() I mean I have reassignment of rows variable later down the code, so will compiler track both and properly close at the end of a function?我的意思是我稍后在代码中重新分配了rows变量,所以编译器会跟踪两者并在函数结束时正确关闭吗?

  2. Is it ok to reuse id shared var or should I redeclare it while iterating within rows.Next() loop?可以重用id shared var 还是应该在rows.Next()循环中迭代时重新声明它?

  3. What's the better approach of having even more queries within one handler?在一个处理程序中拥有更多查询的更好方法是什么? Should I have some kind of Writer that accepts query and slice and populate it with ids retrieved?我应该有某种Writer接受查询和切片并用检索到的 id 填充它吗?

Thanks.谢谢。

I've never worked with go-pg library, and my answer is mostly focused on the other stuff, which are generic, and are not specific to golang or go-pg.我从来没有使用过go-pg库,我的回答主要集中在其他东西上,它们是通用的,并不特定于 golang 或 go-pg。

    1. Regardless of the fact that the rows here has the same reference while being shared between 2 queries (so one rows.Close() call would suffice, unless the library has some special implementation), defining two variables is cleaner, like userRows and bookRows .尽管此处的rows 2 个查询之间共享时具有相同的引用(因此一个rows.Close()调用就足够了,除非库有一些特殊的实现),定义两个变量更清晰,例如userRowsbookRows
    1. Although I already said that I have not worked with go-pg , I believe that you wont need to iterate through rows and scan the id for all the rows manually, I believe that the lib has provided some API like this (based on the quick look on the documentations):虽然我已经说过我没有使用go-pg ,但我相信你不需要遍历行并手动扫描所有行的 id,我相信 lib 提供了一些这样的 API(基于快速查看文档):
     userIds := []int{} err := pgClient.Query(&userIds, "select id from users where ...", args...)
    1. Regarding your second question, it depends on what you mean by "ok".关于您的第二个问题,这取决于您所说的“确定”是什么意思。 Since your doing some synchronous iteration, I don't think it would result into bugs, but when it comes to coding style, personally, I wouldn't do this.由于您进行了一些同步迭代,我认为这不会导致错误,但是就编码风格而言,就个人而言,我不会这样做。
    1. I think that the best thing to do in your case is this:我认为在您的情况下最好的做法是:
     // repo layer func getUserIds(args whatever) ([]int, err) {...} // these can be exposed, based on your packaging logic func getBookIds(args whatever) ([]int, err) {...} // service layer, or wherever you want to aggregate both queries func getUserAndBookIds() ([]int, []int, err) { userIds, err := getUserIds(...) // potential error handling bookIds, err := getBookIds(...) // potential error handling return userIds, bookIds, nil // you have done err handling earlier }
    I think this code is easier to read/maintain.我认为这段代码更容易阅读/维护。 You won't face the variable reassignment and other issues.您不会面临变量重新分配和其他问题。

You can take a look at the go-pg documentations for more details on how to improve your query.您可以查看go-pg 文档以获取有关如何改进查询的更多详细信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 同一项目中的多个模块 - Multiple modules within the same project 具有相同函数名称的多个“类” - Multiple "classes" with same function names 为 postgres 运行多个查询(SELECT * from emp; Select * from adm;)并在两个不同的结构中获得结果 IN GO(GOLANG) - Run multiple queries(SELECT * from emp; Select * from adm;) for postgres and get result in a two different struct IN GO(GOLANG) 在循环中同时从Go中的地图中删除多个值 - Deleting multiple values from a map in Go at the same time within a loop 对多个预期查询使用相同的预期行只为第一个使用 sqlmock 返回结果 - Using same expected rows for multiple expected queries returns result just for the first one with sqlmock 是否有支持非阻塞查询的 Postgres 的 Golang 驱动程序? - Are there Golang drivers for Postgres which support non-blocking queries? 使用 postgres 在 GORM 中使用 struct 进行 Like/gte/lte 查询 - Like/gte/lte queries with struct in GORM using postgres 如何在gorm中处理多个查询 - How to handle multiple queries in gorm golang package 导入流程是如何工作的,有没有办法在同一个模块中多次初始化一个 package? - How does the golang package import flow work and is there a way to initialize one package multiple times within the same module? Postgres:优化并发的同一行更新 - Postgres: Optimising concurrent same row updates
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM