---
sidebar_label: Go
title: TDengine Go Connector
---

`driver-go` is the official Go language connector for TDengine. It implements the [database/sql](https://golang.org/pkg/database/sql/) package, the generic Go language interface to SQL databases. Go developers can use it to develop applications that access TDengine cluster data.

This article describes how to install `driver-go` and connect to TDengine clusters and perform basic operations such as data query and data writing through `driver-go`.

The source code of `driver-go` is hosted on [GitHub](https://github.com/taosdata/driver-go).

## Installation steps
### Use go get to install

```
go get -u github.com/taosdata/driver-go/v2@develop
```
### Manage with go mod

1. Initialize the project with the `go mod` command.

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

2. Introduce taosSql

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

3. Update the dependency packages with `go mod tidy`.

  ```text
  go mod tidy
  ``` 

4. Run the program with `go run taos-demo` or compile the binary with the `go build` command.

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

## Create a connection

### Data source name (DSN)

Data source names have a standard format, e.g. [PEAR DB](http://pear.php.net/manual/en/package.database.db.intro-dsn.php), but no type prefix (square brackets indicate optionally):

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

DSN in full form.

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

### Connecting via connector

_taosRestful_ implements Go's `database/sql/driver` interface via `http client`. You can use the [`database/sql`](https://golang.org/pkg/database/sql/) interface by simply introducing the driver.

Use `taosRestful` as `driverName` and use a correct [DSN](#DSN) as `dataSourceName` with the following parameters supported by the DSN.

* `disableCompression` whether to accept compressed data, default is true do not accept compressed data, set to false if transferring data using gzip compression.
* `readBufferSize` The default size of the buffer for reading data is 4K (4096), which can be adjusted upwards when the query result has a lot of data.

## Sample programs

* [sample program](https://github.com/taosdata/TDengine/tree/develop/examples/go)
* [Video tutorial](https://www.taosdata.com/blog/2020/11/11/1951.html).

## Usage limitations

Since the REST API is stateless, the `use db` syntax will not work. You need to put the db name into the SQL command, e.g. `create table if not exists tb1 (ts timestamp, a int)` to `create table if not exists test.tb1 (ts timestamp, a int)` otherwise it will report the error `[0x217] Database not specified or available`.

You can also put the db name in the DSN by changing `root:taosdata@http(localhost:6041)/` to `root:taosdata@http(localhost:6041)/test`. This method is supported by taosAdapter since TDengine 2.4.0.5. Executing the `create database` statement when the specified db does not exist will not report an error while executing other queries or writing against that db will report an error.

The complete example is as follows.

```go
package main

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

    _ "github.com/taosdata/driver-go/v2/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)
    }
}
```

## Frequently Asked Questions

1. Cannot find the package `github.com/taosdata/driver-go/v2/taosRestful`

  Change the `github.com/taosdata/driver-go/v2` line in the require block of the `go.mod` file to `github.com/taosdata/driver-go/v2 develop`, then execute `go mod tidy`.

2. bind interface in database/sql crashes

  REST API does not support parameter binding related interface. It is recommended to use `db.Exec` and `db.Query`.

3. error `[0x217] Database not specified or available` after executing other statements with `use db` statement

  The execution of SQL command in the REST interface is not contextual, so using `use db` statement will not work, see the usage restrictions section above.

4. use `taosSql` without error but use `taosRestful` with error `[0x217] Database not specified or available`

  Because the REST API is stateless, using the `use db` statement will not take effect. See the usage restrictions section above.

5. Upgrade `github.com/taosdata/driver-go/v2/taosRestful`

  Change the `github.com/taosdata/driver-go/v2` line in the `go.mod` file to `github.com/taosdata/driver-go/v2 develop`, then execute `go mod tidy`.

6. `readBufferSize` parameter has no significant effect after being increased

  Increasing `readBufferSize` will reduce the number of `syscall` calls when fetching results. If the query result is smaller, modifying this parameter will not improve performance significantly. If you increase the parameter value too much, the bottleneck will be parsing JSON data. If you need to optimize the query speed, you must adjust the value based on the actual situation to achieve the best query performance.

7. `disableCompression` parameter is set to `false` when the query efficiency is reduced

  When set `disableCompression` parameter to `false`, the query result will be compressed by `gzip` and then transmitted, so you have to decompress the data by `gzip` after getting it.

8. `go get` command can't get the package, or timeout to get the package

  Set Go proxy `go env -w GOPROXY=https://goproxy.cn,direct`.

## Common APIs

### database/sql API

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

  Use This API to open a DB, returning an object of type \*DB.

:::info
This API is created successfully without checking permissions, but only when you execute a Query or Exec, and check if user/password/host/port is legal.

:::

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

  `sql.Open` built-in method to execute non-query related SQL.

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

  `sql.Open` Built-in method to execute query statements.


## API Reference

Full API see [driver-go documentation](https://pkg.go.dev/github.com/taosdata/driver-go/v2)