[Alt](https://res.cloudinary.com/practicaldev/image/fetch/s--cL3fS3ZP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev- to-uploads.s3.amazonaws.com/uploads/articles/e0wsvzqxax4rqmokmx2o.png)

应用程序和数据库就像牛奶和饼干一样;今天的菜单上有一块 PostgreSQL 口味的饼干,里面有一点清爽的 Go 牛奶。我选择了两个我最喜欢的 Go 库来展示如何连接和使用您的 Aiven PostgreSQL 服务。这些库是pgx,它是database/sql和Squirrel的一个很好的 PostgreSQL 特定替代品,因为我喜欢这个名字(它也有一些非常酷的特性)。

从数据库开始

已经有一个方便的 PostgreSQL 数据库是有意义的,最好是其中有一些数据。如果您还没有 Aiven 帐户,那么注册并启动 PostgreSQL 服务。如果您已经有一些数据可以使用,那就太好了!我正在使用来自开普勒太空任务的一些开放数据,您可以跟随最近的博客文章自行设置。

在 Aiven 控制台中,复制 Postgres 的连接字符串 - 或者如果您使用不同的数据库,请复制postgres://....连接字符串。

从 Go 连接到 PostgreSQL

Go 在其database/sql库中内置了数据库支持,但它非常通用,因为它必须能够应对如此多不同的数据库平台。对于专门连接到 PostgreSQL 的应用程序,使用专业库是有意义的。

对于这个例子,我选择了jackc/pgx,它是 PostgreSQL 特有的,除了提高性能外,它还具有一些关于理解 PostgreSQL 数据类型的不错的特性。整体模式与使用database/sql的其他应用程序没有根本区别,这让人感觉很熟悉。

将您之前复制的连接字符串设置为DATABASE_URL环境变量。然后用go mod init pgfun初始化你的 go 应用程序;pgx使用 go 模块。

当您完成所有设置后,尝试下面的代码示例连接到数据库并运行一个查询(我的数据库中有系外行星数据):


package main

import (
    "context"
    "fmt"
    "os"

    "github.com/jackc/pgx/v4/pgxpool"
)

func main() {
    dbpool, dberr := pgxpool.Connect(context.Background(), os.Getenv("DATABASE_URL"))
    if dberr != nil {
        panic("Unable to connect to database")
    }
    defer dbpool.Close()

    sql := "SELECT kepler_name, koi_score " +
        "FROM cumulative " +
        "WHERE kepler_name IS NOT NULL AND koi_pdisposition = 'CANDIDATE' " +
        "ORDER BY koi_score LIMIT 5"
    rows, sqlerr := dbpool.Query(context.Background(), sql)
    if sqlerr != nil {
        panic(fmt.Sprintf("QueryRow failed: %v", sqlerr))
    }

    for rows.Next() {
        var planet_name string
        var score float64
        rows.Scan(&planet_name, &score)
        fmt.Printf("%s\t%.2f\n", planet_name, score)
    }
}

进入全屏模式 退出全屏模式

main()函数中,首先代码使用连接池pgx的特性连接到数据库。作为一般规则,我认为 PostgreSQL 的连接池是一个明智之举,这就是为什么在这里使用它的原因。

然后是一个简单的 SQL 语句,显示开普勒任务分配给“候选”状态的系外行星,以及他们对这是一颗真实行星的信心。该语句有一个行限制(数据集有大约 2k 行没有限制),因此您只能在最后一部分中看到五个置信度得分最低的行星,它遍历行并将数据作为变量读取。

我喜欢这里的名字——如果你有兴趣,你甚至可以在系外行星目录中查找行星。我花了太多时间浏览它,科学是王牌!

回顾一下,我们有一个 PostgreSQL 连接字符串、一个 Go 数据库库和一个硬编码的 SQL 查询。下一步是什么?

带松鼠的流体接口

虽然pgx库是 PostgreSQL 特定的替代database/sql,但它也有一个兼容的接口。如果您想切换现有应用程序,这是理想的选择,但这也意味着其他旨在与database/sql完美配合的工具也可以与pgx配合使用。这对我来说是个好消息,因为我想找到比我的硬编码 SQL 字符串更优雅的东西。

松鼠!

不,我没有分心,它是一个 SQL 库。虽然,它有点像一个闪亮的玩具。它是用于构建 SQL 查询的流畅界面,并且 SQL 很适合以这种方式思考。

在此界面中重建我们现有的 SQL 查询会产生如下内容:

    planets := psql.Select("kepler_name", "koi_score").
        From("cumulative").
        Where(sq.NotEq{"kepler_name": nil}).
        Where(sq.Eq{"koi_pdisposition": "CANDIDATE"}).
        OrderBy("koi_score").
        Limit(5)

进入全屏模式 退出全屏模式

它更易于管理,我可以想象在实际应用程序中构建它比将 SQL 字符串连接在一起要容易得多。仍然可以通过调用planets.ToSql()来检查它作为字符串构建的 SQL,这是一个很好的接触。

pgx切换到“假装是database/sql”模式需要一些重构。我还需要一勺秘方来让 Squirrel 与 PostgreSQL 很好地配合,所以这里是整个可运行的示例。它期望数据库连接字符串在DATABASE_URL中,与前面的示例一样:

package main

import (
    "database/sql"
    "fmt"
    "os"

    sq "github.com/Masterminds/squirrel"
    _ "github.com/jackc/pgx/v4/stdlib"
)

func main() {
    db, err := sql.Open("pgx", os.Getenv("DATABASE_URL"))
    if err != nil {
        panic("Unable to connect to database")
    }
    defer db.Close()

    // a little magic to tell squirrel it's postgres
    psql := sq.StatementBuilder.PlaceholderFormat(sq.Dollar)

    planets := psql.Select("kepler_name", "koi_score").
        From("cumulative").
        Where(sq.NotEq{"kepler_name": nil}).
        Where(sq.Eq{"koi_pdisposition": "CANDIDATE"}).
        OrderBy("koi_score").
        Limit(5)

    rows, sqlerr := planets.RunWith(db).Query()
    if sqlerr != nil {
        panic(fmt.Sprintf("QueryRow failed: %v", sqlerr))
    }

    for rows.Next() {
        var planet_name string
        var score float64
        rows.Scan(&planet_name, &score)
        fmt.Printf("%s\t%.2f\n", planet_name, score)
    }
}

进入全屏模式 退出全屏模式

请注意,这次pgx导入不同,以获取 Squirrel 在其RunWith()方法中期望的database/sql兼容库。连接步骤也有一些变化,所以不要试图修改前面的例子;这个不同。

psql变量包含一个重新配置的松鼠,这是必需的,因为 PostgreSQL 处理占位符的方式略有不同。跳过这会导致代码告诉您在LIMIT子句附近存在语法错误。希望现在我已经写下来了,我尊贵的读者可以避免这个问题,下次我什至可以记住这个!

Go 和 PostgreSQL 的乐趣

这是一个轻量级的介绍,向您展示了几个我最喜欢的 Go 和 PostgreSQL 应用程序库——当然还有一个开放的数据集可供使用,乐趣成倍增加:)

以下是一些相关链接和进一步阅读,如果您有任何问题,请通过Twitter与我们联系。我们总是很高兴聊天。

  • Aiven PostgreSQL 入门

  • 将系外行星导入您的 PostgreSQL

  • Aiven 连接的代码示例

  • Postgres13 可用

Logo

PostgreSQL社区为您提供最前沿的新闻资讯和知识内容

更多推荐