---
toc_max_heading_level: 4
sidebar_position: 4
sidebar_label: Go
title: TDengine Go Connector
---

`driver-go` 是 TDengine 的官方 Go 语言连接器，实现了 Go 语言 [database/sql](https://golang.org/pkg/database/sql/)  包的接口。Go 开发人员可以通过它开发存取 TDengine 集群数据的应用软件。

本文介绍如何安装 `driver-go`，并通过 `driver-go` 连接 TDengine Cloud 集群、进行数据查询、数据写入等基本操作。

`driver-go` 的源码托管在 [GitHub](https://github.com/taosdata/driver-go)。

## 版本支持

请参考[版本支持列表](../#版本支持)

## 安装步骤

### 安装前准备

* 安装 Go 开发环境（Go 1.14 及以上，GCC 4.8.5 及以上）
* 如果使用原生连接器，请安装 TDengine 客户端驱动，具体步骤请参考[安装客户端驱动](../#安装客户端驱动)

配置好环境变量，检查命令：

* ```go env```
* ```gcc -v```

### 使用 go get 安装

`go get -u github.com/taosdata/driver-go/v3@latest`

### 使用 go mod 管理

1. 使用 `go mod` 命令初始化项目：

  ```text
  go mod init taos-demo
  ```

2. 引入 taosSql ：

  ```go
  import (
    "database/sql"
    _ "github.com/taosdata/driver-go/v3/taosSql"
  )
  ```

3. 使用 `go mod tidy` 更新依赖包：

  ```text
  go mod tidy
  ```

4. 使用 `go run taos-demo` 运行程序或使用 `go build` 命令编译出二进制文件。

  ```text
  go run taos-demo
  go build
  ```

## 建立连接

### 数据源名称（DSN）

数据源名称具有通用格式，例如 [PEAR DB](http://pear.php.net/manual/en/package.database.db.intro-dsn.php)，但没有类型前缀（方括号表示可选）：

``` text
[username[:password]@][protocol[(address)]]/[dbname][?param1=value1&...&paramN=valueN]
```

完整形式的 DSN：

```text
username:password@protocol(address)/dbname?param=value
```

### 使用连接器进行连接

_taosRestful_ 通过 `http client` 实现了 Go 的 `database/sql/driver` 接口。只需要引入驱动就可以使用[`database/sql`](https://golang.org/pkg/database/sql/)的接口。

使用 `taosRestful` 作为 `driverName` 并且使用一个正确的 [DSN](#DSN) 作为 `dataSourceName`，DSN 支持的参数：

* `disableCompression` 是否接受压缩数据，默认为 true 不接受压缩数据，如果传输数据使用 gzip 压缩设置为 false。
* `readBufferSize` 读取数据的缓存区大小默认为 4K（4096），当查询结果数据量多时可以适当调大该值。

## 使用示例

### 更多示例程序

* [示例程序](https://github.com/taosdata/driver-go/tree/3.0/examples)
* [视频教程](https://www.taosdata.com/blog/2020/11/11/1951.html)。

## 使用限制

由于 REST 接口无状态所以 `use db` 语法不会生效，需要将 db 名称放到 SQL 语句中，如：`create table if not exists tb1 (ts timestamp, a int)`改为`create table if not exists test.tb1 (ts timestamp, a int)`否则将报错`[0x217] Database not specified or available`。

也可以将 db 名称放到 DSN 中，将 `root:taosdata@http(localhost:6041)/` 改为 `root:taosdata@http(localhost:6041)/test`。当指定的 db 不存在时执行 `create database` 语句不会报错，而执行针对该 db 的其他查询或写入操作会报错。

完整示例如下：

```go
package main

import (
    "database/sql"
    "fmt"
    "time"

    _ "github.com/taosdata/driver-go/v3/taosRestful"
)

func main() {
    var taosDSN = "root:taosdata@http(localhost:6041)/test"
    taos, err := sql.Open("taosRestful", taosDSN)
    if err != nil {
        fmt.Println("failed to connect TDengine, err:", err)
        return
    }
    defer taos.Close()
    taos.Exec("create database if not exists test")
    taos.Exec("create table if not exists tb1 (ts timestamp, a int)")
    _, err = taos.Exec("insert into tb1 values(now, 0)(now+1s,1)(now+2s,2)(now+3s,3)")
    if err != nil {
        fmt.Println("failed to insert, err:", err)
        return
    }
    rows, err := taos.Query("select * from tb1")
    if err != nil {
        fmt.Println("failed to select from table, err:", err)
        return
    }

    defer rows.Close()
    for rows.Next() {
        var r struct {
            ts time.Time
            a  int
        }
        err := rows.Scan(&r.ts, &r.a)
        if err != nil {
            fmt.Println("scan error:\n", err)
            return
        }
        fmt.Println(r.ts, r.a)
    }
}
```

## 常见问题

1. database/sql 中 stmt（参数绑定）相关接口崩溃

  REST 不支持参数绑定相关接口，建议使用`db.Exec`和`db.Query`。

2. 使用 `use db` 语句后执行其他语句报错 `[0x217] Database not specified or available`

  在 REST 接口中 SQL 语句的执行无上下文关联，使用 `use db` 语句不会生效，解决办法见上方使用限制章节。

3. 使用 taosSql 不报错使用 taosRestful 报错 `[0x217] Database not specified or available`

  因为 REST 接口无状态，使用 `use db` 语句不会生效，解决办法见上方使用限制章节。

4. `readBufferSize` 参数调大后无明显效果

  `readBufferSize` 调大后会减少获取结果时 `syscall` 的调用。如果查询结果的数据量不大，修改该参数不会带来明显提升，如果该参数修改过大，瓶颈会在解析 JSON 数据。如果需要优化查询速度，需要根据实际情况调整该值来达到查询效果最优。

5. `disableCompression` 参数设置为 `false` 时查询效率降低

  当 `disableCompression` 参数设置为 `false` 时查询结果会使用 `gzip` 压缩后传输，拿到数据后要先进行 `gzip` 解压。

6. `go get` 命令无法获取包，或者获取包超时

  设置 Go 代理 `go env -w GOPROXY=https://goproxy.cn,direct`。

## 常用 API

### database/sql API

* `sql.Open(DRIVER_NAME string, dataSourceName string) *DB`

  该 API 用来打开 DB，返回一个类型为 \*DB 的对象。

:::info
该 API 成功创建的时候，并没有做权限等检查，只有在真正执行 Query 或者 Exec 的时候才能真正的去创建连接，并同时检查 user/password/host/port 是不是合法。
:::

* `func (db *DB) Exec(query string, args ...interface{}) (Result, error)`

  `sql.Open` 内置的方法，用来执行非查询相关 SQL。

* `func (db *DB) Query(query string, args ...interface{}) (*Rows, error)`

  `sql.Open` 内置的方法，用来执行查询语句。

## API 参考

全部 API 见 [driver-go 文档](https://pkg.go.dev/github.com/taosdata/driver-go/v3)
