|
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