|
1 | 1 | ---
|
2 |
| -title: Golang |
| 2 | +title: Go |
3 | 3 | ---
|
4 | 4 |
|
5 |
| -import StepsWrap from '@site/src/components/StepsWrap'; |
6 |
| -import StepContent from '@site/src/components/Steps/step-content'; |
| 5 | +# Databend Go 驱动 |
7 | 6 |
|
8 |
| -Databend 提供了一个用 Golang 编写的驱动程序(databend-go),方便使用 Golang 编程语言开发应用程序并与 Databend 建立连接。 |
| 7 | +官方 Go 驱动,提供标准的 `database/sql` 接口,可与现有 Go 应用程序无缝集成。 |
9 | 8 |
|
10 |
| -有关安装说明、示例和源代码,请参阅 GitHub [databend-go](https://github.com/databendlabs/databend-go) 仓库。 |
| 9 | +## 安装 |
11 | 10 |
|
12 |
| -## 数据类型映射 |
13 |
| - |
14 |
| -下表说明了 Databend 数据类型与其对应的 Go 等效类型之间的对应关系: |
15 |
| - |
16 |
| -| Databend | Go | |
17 |
| -| --- | --- | |
18 |
| -| TINYINT | int8 | |
19 |
| -| SMALLINT | int16 | |
20 |
| -| INT | int32 | |
21 |
| -| BIGINT | int64 | |
22 |
| -| TINYINT UNSIGNED | uint8 | |
23 |
| -| SMALLINT UNSIGNED | uint16 | |
24 |
| -| INT UNSIGNED | uint32 | |
25 |
| -| BIGINT UNSIGNED | uint64 | |
26 |
| -| Float32 | float32 | |
27 |
| -| Float64 | float64 | |
28 |
| -| Bitmap | string | |
29 |
| -| Decimal | decimal.Decimal | |
30 |
| -| String | string | |
31 |
| -| Date | time.Time | |
32 |
| -| DateTime | time.Time | |
33 |
| -| Array(T) | string | |
34 |
| -| Tuple(T1, T2, ...) | string | |
35 |
| -| Variant | string | |
36 |
| - |
37 |
| -## Databend Go 驱动行为摘要 |
38 |
| - |
39 |
| -Databend Go 驱动与 ["database/sql"](https://pkg.go.dev/database/sql) 接口规范兼容。以下是一些常见的基本行为,以及涉及的关键函数和其背后的原理。 |
40 |
| - |
41 |
| -| 基本行为 | 涉及的关键函数 | 原理 | |
42 |
| -| --- | --- | --- | |
43 |
| -| 创建连接 | `DB.Open` | 使用 DSN 字符串和 `DB.Open` 方法建立与 Databend 的连接。<br /><br />DSN 字符串格式为 `https://user:password@host/database?<query_option>=<value>`。 | |
44 |
| -| 执行语句 | `DB.Exec` | `DB.Exec` 方法使用 `v1/query` 接口执行 SQL 语句,用于创建、删除表和插入数据。 | |
45 |
| -| 批量插入 | `DB.Begin`, `Tx.Prepare`, `Stmt.Exec`, `Tx.Commit` | 批量插入/替换数据(`INSERT INTO` 和 `REPLACE INTO`)通过事务处理。<br /><br />使用 `Stmt.Exec` 将尽可能多的数据添加到预处理语句对象中;数据将被附加到一个文件中。<br /><br />执行 `Tx.Commit()` 将最终把数据上传到内置的暂存区(Stage)并执行插入/替换操作,使用[暂存区附件(Stage Attachment)](/developer/apis/http#stage-attachment)。 | |
46 |
| -| 查询单行 | `DB.QueryRow`, `Row.Scan` | 使用 `DB.QueryRow` 方法查询单行数据并返回一个 `*sql.Row`,然后调用 `Row.Scan` 将列数据映射到变量。 | |
47 |
| -| 遍历多行 | `DB.Query`, `Rows.Next`, `Rows.Scan` | 使用 `DB.Query` 方法查询多行数据并返回一个 `*sql.Rows` 结构,使用 `Rows.Next` 方法遍历行,并使用 `Rows.Scan` 将数据映射到变量。 | |
48 |
| -| 上传到内部暂存区(Stage) | `APIClient.UploadToStage` | 将数据上传到暂存区(Stage)。默认情况下,使用 `PRESIGN UPLOAD` 获取 URL,如果 PRESIGN 被禁用,则使用 `v1/upload_to_stage` API。 | |
49 |
| - |
50 |
| -## 教程一:使用 Golang 与 Databend 集成 |
51 |
| - |
52 |
| -在开始之前,请确保您已成功在本地安装 Databend。有关详细说明,请参阅[本地和 Docker 部署](/guides/deploy/deploy/non-production/deploying-local)。 |
53 |
| - |
54 |
| -### 步骤一:准备一个 SQL 用户帐户 |
55 |
| - |
56 |
| -要将您的程序连接到 Databend 并执行 SQL 操作,您必须在代码中提供一个具有适当权限的 SQL 用户帐户。如果需要,请在 Databend 中创建一个,并确保该 SQL 用户仅拥有必要的权限以确保安全。 |
57 |
| - |
58 |
| -本教程以一个名为 'user1'、密码为 'abc123' 的 SQL 用户为例。由于程序将向 Databend 写入数据,该用户需要 ALL 权限。有关如何管理 SQL 用户及其权限的信息,请参阅[用户和角色](/sql/sql-commands/ddl/user/)。 |
59 |
| - |
60 |
| -```sql |
61 |
| -CREATE USER user1 IDENTIFIED BY 'abc123'; |
62 |
| -GRANT ALL on *.* TO user1; |
| 11 | +```bash |
| 12 | +go get github.com/databendlabs/databend-go |
63 | 13 | ```
|
64 | 14 |
|
65 |
| -### 步骤二:编写一个 Golang 程序 |
| 15 | +**连接字符串**:有关 DSN 格式和连接示例,请参阅[驱动概述](./index.md#connection-string-dsn)。 |
66 | 16 |
|
67 |
| -在此步骤中,您将创建一个与 Databend 通信的简单 Golang 程序。该程序将涉及创建表、插入数据和执行数据查询等任务。 |
| 17 | +--- |
68 | 18 |
|
69 |
| -<StepsWrap> |
| 19 | +## 主要特性 |
70 | 20 |
|
71 |
| -<StepContent number="1"> |
| 21 | +- ✅ **标准接口**:完全兼容 `database/sql` |
| 22 | +- ✅ **连接池**:内置连接管理 |
| 23 | +- ✅ **批量操作**:通过事务高效执行批量插入 |
| 24 | +- ✅ **类型安全**:全面的 Go 类型映射 |
72 | 25 |
|
73 |
| -### 将以下代码复制并粘贴到 main.go 文件中 |
| 26 | +## 数据类型映射 |
74 | 27 |
|
75 |
| -:::note |
| 28 | +| Databend | Go | 说明 | |
| 29 | +|----------|----|---------| |
| 30 | +| **整数** | | | |
| 31 | +| `TINYINT` | `int8` | | |
| 32 | +| `SMALLINT` | `int16` | | |
| 33 | +| `INT` | `int32` | | |
| 34 | +| `BIGINT` | `int64` | | |
| 35 | +| `TINYINT UNSIGNED` | `uint8` | | |
| 36 | +| `SMALLINT UNSIGNED` | `uint16` | | |
| 37 | +| `INT UNSIGNED` | `uint32` | | |
| 38 | +| `BIGINT UNSIGNED` | `uint64` | | |
| 39 | +| **浮点数** | | | |
| 40 | +| `FLOAT` | `float32` | | |
| 41 | +| `DOUBLE` | `float64` | | |
| 42 | +| **其他类型** | | | |
| 43 | +| `DECIMAL` | `decimal.Decimal` | 需要 decimal 包 | |
| 44 | +| `STRING` | `string` | | |
| 45 | +| `DATE` | `time.Time` | | |
| 46 | +| `TIMESTAMP` | `time.Time` | | |
| 47 | +| `ARRAY(T)` | `string` | JSON 编码 | |
| 48 | +| `TUPLE(...)` | `string` | JSON 编码 | |
| 49 | +| `VARIANT` | `string` | JSON 编码 | |
| 50 | +| `BITMAP` | `string` | Base64 编码 | |
76 | 51 |
|
77 |
| -- 下面的代码以一个名为 'user1'、密码为 'abc123' 的 SQL 用户连接到本地 Databend 为例。您可以随意使用自己的值,但请保持格式相同。 |
78 |
| -- 下面代码中 `hostname` 的值必须与您的 Databend 查询服务的 HTTP 处理器设置保持一致。 |
79 |
| - ::: |
| 52 | +--- |
80 | 53 |
|
81 |
| -```go title='main.go' |
82 |
| -package main |
| 54 | +## 基本用法 |
83 | 55 |
|
| 56 | +```go |
84 | 57 | import (
|
85 |
| - "database/sql" |
86 |
| - "fmt" |
87 |
| - "log" |
88 |
| - |
89 |
| - _ "github.com/databendcloud/databend-go" |
90 |
| -) |
| 58 | + "database/sql" |
| 59 | + "fmt" |
| 60 | + "log" |
91 | 61 |
|
92 |
| -const ( |
93 |
| - username = "user1" |
94 |
| - password = "abc123" |
95 |
| - hostname = "127.0.0.1:8000" |
| 62 | + _ "github.com/databendlabs/databend-go" |
96 | 63 | )
|
97 | 64 |
|
98 |
| -type Book struct { |
99 |
| - Title string |
100 |
| - Author string |
101 |
| - Date string |
| 65 | +// 连接到 Databend |
| 66 | +db, err := sql.Open("databend", "<your-dsn>") |
| 67 | +if err != nil { |
| 68 | + log.Fatal(err) |
102 | 69 | }
|
| 70 | +defer db.Close() |
103 | 71 |
|
104 |
| -func dsn() string { |
105 |
| - return fmt.Sprintf("databend://%s:%s@%s?sslmode=disable", username, password, hostname) |
| 72 | +// DDL:创建表 |
| 73 | +_, err = db.Exec("CREATE TABLE users (id INT, name STRING)") |
| 74 | +if err != nil { |
| 75 | + log.Fatal(err) |
106 | 76 | }
|
107 | 77 |
|
108 |
| -func main() { |
109 |
| - db, err := sql.Open("databend", dsn()) |
110 |
| - |
111 |
| - if err != nil { |
112 |
| - log.Fatal(err) |
113 |
| - } |
114 |
| - defer db.Close() |
115 |
| - |
116 |
| - err = db.Ping() |
117 |
| - if err != nil { |
118 |
| - log.Fatal(err) |
119 |
| - } |
120 |
| - log.Println("Connected") |
121 |
| - |
122 |
| - // 如果数据库不存在,则创建 |
123 |
| - dbSql := "CREATE DATABASE IF NOT EXISTS book_db" |
124 |
| - _, err = db.Exec(dbSql) |
125 |
| - if err != nil { |
126 |
| - log.Fatal(err) |
127 |
| - } |
128 |
| - log.Println("Create database book_db success") |
129 |
| - |
130 |
| - // 使用 book_db 数据库 |
131 |
| - _, err = db.Exec("USE book_db") |
132 |
| - if err != nil { |
133 |
| - log.Fatal(err) |
134 |
| - } |
135 |
| - |
136 |
| - // 创建表。 |
137 |
| - sql := "create table if not exists books(title VARCHAR, author VARCHAR, date VARCHAR)" |
138 |
| - _, err = db.Exec(sql) |
139 |
| - if err != nil { |
140 |
| - log.Fatal(err) |
141 |
| - } |
142 |
| - log.Println("Create table: books") |
143 |
| - |
144 |
| - // 插入 1 行。 |
145 |
| - _, err = db.Exec("INSERT INTO books VALUES(?, ?, ?)", "mybook", "author", "2022") |
146 |
| - if err != nil { |
147 |
| - log.Fatal(err) |
148 |
| - } |
149 |
| - log.Println("Insert 1 row") |
150 |
| - |
151 |
| - // 查询。 |
152 |
| - res, err := db.Query("SELECT * FROM books") |
153 |
| - if err != nil { |
154 |
| - log.Fatal(err) |
155 |
| - } |
156 |
| - |
157 |
| - for res.Next() { |
158 |
| - var book Book |
159 |
| - err := res.Scan(&book.Title, &book.Author, &book.Date) |
160 |
| - if err != nil { |
161 |
| - log.Fatal(err) |
162 |
| - } |
163 |
| - |
164 |
| - log.Printf("Select:%v", book) |
165 |
| - } |
166 |
| - db.Exec("drop table books") |
167 |
| - db.Exec("drop database book_db") |
| 78 | +// 写入:插入数据 |
| 79 | +_, err = db.Exec("INSERT INTO users VALUES (?, ?)", 1, "Alice") |
| 80 | +if err != nil { |
| 81 | + log.Fatal(err) |
168 | 82 | }
|
169 |
| -``` |
170 |
| - |
171 |
| -</StepContent> |
172 |
| - |
173 |
| -<StepContent number="2"> |
174 |
| - |
175 |
| -### 安装依赖。 |
176 |
| - |
177 |
| -```shell |
178 |
| -go mod init databend-golang |
179 |
| -``` |
180 |
| - |
181 |
| -```text title='go.mod' |
182 |
| -module databend-golang |
183 | 83 |
|
184 |
| -go 1.20 |
185 |
| -
|
186 |
| -require github.com/databendcloud/databend-go v0.3.10 |
187 |
| -
|
188 |
| -require ( |
189 |
| - github.com/BurntSushi/toml v1.2.1 // indirect |
190 |
| - github.com/avast/retry-go v3.0.0+incompatible // indirect |
191 |
| - github.com/google/uuid v1.3.0 // indirect |
192 |
| - github.com/pkg/errors v0.9.1 // indirect |
193 |
| - github.com/sirupsen/logrus v1.9.0 // indirect |
194 |
| - golang.org/x/sys v0.5.0 // indirect |
195 |
| -) |
196 |
| -``` |
197 |
| - |
198 |
| -</StepContent> |
199 |
| - |
200 |
| -<StepContent number="3"> |
201 |
| - |
202 |
| -### 运行程序。 |
203 |
| - |
204 |
| -```shell |
205 |
| -go run main.go |
206 |
| -``` |
207 |
| - |
208 |
| -```text title='Outputs' |
209 |
| -2023/02/24 23:57:31 Connected |
210 |
| -2023/02/24 23:57:31 Create database book_db success |
211 |
| -2023/02/24 23:57:31 Create table: books |
212 |
| -2023/02/24 23:57:31 Insert 1 row |
213 |
| -2023/02/24 23:57:31 Select:{mybook author 2022} |
214 |
| -``` |
215 |
| - |
216 |
| -</StepContent> |
217 |
| - |
218 |
| -</StepsWrap> |
219 |
| - |
220 |
| -## 教程二:使用 Golang 与 Databend Cloud 集成 |
221 |
| - |
222 |
| -在开始之前,请确保您已成功创建了一个计算集群(Warehouse)并获取了连接信息。有关如何操作,请参阅[连接到计算集群(Warehouse)](/guides/cloud/using-databend-cloud/warehouses#connecting)。 |
223 |
| - |
224 |
| -### 步骤一:创建一个 Go 模块 |
225 |
| - |
226 |
| -```shell |
227 |
| -$ mkdir sample |
228 |
| -$ cd sample |
229 |
| -$ go mod init cloud.databend.com/sample |
230 |
| -``` |
231 |
| - |
232 |
| -### 步骤二:安装依赖 |
233 |
| - |
234 |
| -```go |
235 |
| -$ go get github.com/databendcloud/databend-go |
236 |
| -``` |
237 |
| - |
238 |
| -### 步骤三:使用 databend-go 连接 |
239 |
| - |
240 |
| -创建一个名为 `main.go` 的文件,内容如下: |
241 |
| - |
242 |
| -```go |
243 |
| -package main |
244 |
| - |
245 |
| -import ( |
246 |
| - "database/sql" |
247 |
| - "fmt" |
248 |
| - |
249 |
| - _ "github.com/databendcloud/databend-go" |
250 |
| -) |
251 |
| - |
252 |
| -func main() { |
253 |
| - dsn := "databend://{USER}:{PASSWORD}@${HOST}:443/{DATABASE}?&warehouse={WAREHOUSE_NAME}"; |
254 |
| - conn, err := sql.Open("databend", dsn) |
255 |
| - if err != nil { |
256 |
| - fmt.Println(err) |
257 |
| - } |
258 |
| - conn.Exec(`DROP TABLE IF EXISTS data`) |
259 |
| - createTable := `CREATE TABLE IF NOT EXISTS data ( |
260 |
| - i64 Int64, |
261 |
| - u64 UInt64, |
262 |
| - f64 Float64, |
263 |
| - s String, |
264 |
| - s2 String, |
265 |
| - a16 Array(Int16), |
266 |
| - a8 Array(UInt8), |
267 |
| - d Date, |
268 |
| - t DateTime)` |
269 |
| - _, err = conn.Exec(createTable) |
270 |
| - if err != nil { |
271 |
| - fmt.Println(err) |
272 |
| - } |
273 |
| - scope, err := conn.Begin() |
274 |
| - batch, err := scope.Prepare(fmt.Sprintf("INSERT INTO %s VALUES", "data")) |
275 |
| - if err != nil { |
276 |
| - fmt.Println(err) |
277 |
| - } |
278 |
| - for i := 0; i < 10; i++ { |
279 |
| - _, err = batch.Exec( |
280 |
| - "1234", |
281 |
| - "2345", |
282 |
| - "3.1415", |
283 |
| - "test", |
284 |
| - "test2", |
285 |
| - "[4, 5, 6]", |
286 |
| - "[1, 2, 3]", |
287 |
| - "2021-01-01", |
288 |
| - "2021-01-01 00:00:00", |
289 |
| - ) |
290 |
| - } |
291 |
| - err = scope.Commit() |
292 |
| - if err != nil { |
293 |
| - fmt.Println(err) |
294 |
| - } |
| 84 | +// 查询:选择数据 |
| 85 | +var id int |
| 86 | +var name string |
| 87 | +err = db.QueryRow("SELECT id, name FROM users WHERE id = ?", 1).Scan(&id, &name) |
| 88 | +if err != nil { |
| 89 | + log.Fatal(err) |
295 | 90 | }
|
296 |
| -``` |
297 | 91 |
|
298 |
| -:::tip |
299 |
| -将代码中的 `{USER}, {PASSWORD}, {HOST}, {WAREHOUSE_NAME} 和 {DATABASE}` 替换为您的连接信息。有关如何获取连接信息,请参阅[连接到计算集群(Warehouse)](/guides/cloud/using-databend-cloud/warehouses#connecting)。 |
300 |
| -::: |
| 92 | +fmt.Printf("User: %d, %s\n", id, name) |
| 93 | +``` |
301 | 94 |
|
302 |
| -### 步骤四:运行 main.go |
| 95 | +## 相关资源 |
303 | 96 |
|
304 |
| -```shell |
305 |
| -$ go run main.go |
306 |
| -``` |
| 97 | +- **GitHub 仓库**:[databend-go](https://github.com/databendlabs/databend-go) |
| 98 | +- **Go 包**:[pkg.go.dev](https://pkg.go.dev/github.com/datafuselabs/databend-go) |
| 99 | +- **示例**:[GitHub 示例](https://github.com/databendlabs/databend-go/tree/main/examples) |
0 commit comments