You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Golang中使用ODBC连接Dremio失败的问题求助

解决Golang连接Dremio时"missing username and password"错误

你遇到的这个错误,本质是你使用的github.com/pinpt/go-dremio/driver驱动,对DSN(数据源名称)的格式有特定要求,而你当前拼接的键值对空格分隔格式,驱动无法正确解析出用户名和密码,所以才会报“缺少用户名密码”的错误。

问题根源

pinpt/go-dremio驱动要求DSN采用URL风格的格式,而不是你现在用的类似PostgreSQL的空格分隔键值对格式。驱动期望的DSN结构是:

dremio://<用户名>:<密码>@<主机>:<端口>/?sslmode=disable

你当前拼接的host=xxx port=xxx user=xxx...格式,驱动无法识别其中的userpassword字段,自然会报错。

解决方案

按照驱动要求的URL格式修改DSN拼接逻辑,同时注意处理特殊字符,具体步骤如下:

  1. 修改DSN拼接代码
    替换你当前的drminfo拼接代码为URL格式,同时转义用户名密码中的特殊字符(比如@、:、/等),避免解析错误:

    import "net/url" // 需要额外导入这个包处理特殊字符转义
    
    // ...
    
    escapedUser := url.QueryEscape(user)
    escapedPassword := url.QueryEscape(password)
    // 拼接符合要求的URL风格DSN
    drminfo := fmt.Sprintf("dremio://%s:%s@%s:%d/?sslmode=disable", escapedUser, escapedPassword, host, port)
    
  2. 添加连接测试(可选但推荐)
    sql.Open()只是创建连接池,不会立刻建立实际连接,建议在Open之后调用db.Ping()验证连接是否成功,这样能更早发现问题:

    db, err := sql.Open("dremio", drminfo)
    if err != nil {
        log.Fatal("Failed to initialize connection pool:", err)
    }
    // 测试实际连接
    if err := db.Ping(); err != nil {
        log.Fatal("Failed to connect to Dremio:", err)
    }
    
  3. 修改后的完整函数示例

    import (
        "database/sql"
        "fmt"
        "log"
        "net/url"
        "gographqlservice/graph/model"
        _ "github.com/pinpt/go-dremio/driver"
    )
    
    const (
        host     = "dremio.xyz.abc.com"
        user     = "user1"
        password = "user_password"
        port     = 32010
    )
    
    func GetAsset(id string) (*model.Asset, error) {
        // 转义特殊字符
        escapedUser := url.QueryEscape(user)
        escapedPassword := url.QueryEscape(password)
        // 拼接URL风格DSN
        drminfo := fmt.Sprintf("dremio://%s:%s@%s:%d/?sslmode=disable", escapedUser, escapedPassword, host, port)
    
        db, err := sql.Open("dremio", drminfo)
        if err != nil {
            log.Fatal("Failed to initialize connection pool:", err)
        }
        // 验证连接
        if err := db.Ping(); err != nil {
            log.Fatal("Failed to connect to Dremio:", err)
        }
    
        rows, err := db.Query("SELECT * FROM space.xyz.\"assets\" WHERE ASSET_ID = ?", id)
        if err != nil {
            log.Fatal(err)
        }
        var asset model.Asset
        defer rows.Close()
        for rows.Next() {
            // 你的字段扫描逻辑
            // 示例:err = rows.Scan(&asset.ID, &asset.Name, ...)
            // 记得处理扫描错误
        }
        if err := rows.Err(); err != nil {
            log.Fatal(err)
        }
        defer db.Close()
        return &asset, nil
    }
    

额外注意事项

  • 如果你的Dremio实例启用了SSL,需要把sslmode=disable改成sslmode=enable,并且确保驱动能正确处理证书(如果需要自定义证书,可能需要额外配置)。
  • 确认Dremio的端口是否正确:你用的32010是Dremio的Flight SQL端口,而常规ODBC/JDBC端口是31010,具体可以和你的Dremio管理员确认配置。

内容的提问来源于stack exchange,提问作者Namrata Kumari

火山引擎 最新活动