(GoLang) panic: sql: Register called twice for driver postgres

Issue

I have probably spent way to much time on this, so I decided to try here.
I’m having trouble figuring out why my Register is being called twice?
Best I can figure, it seems to be calling once at sql.Register() and again at sqlx.Connect(). But if I remove the sql.Register(), then theres no drivers.

Honestly, I am pretty new to GoLang, I’m hoping for any sort of direction here.

Code – w/o sql.Register

package main

import (
    "fmt"

    "database/sql"

    "github.com/jmoiron/sqlx"
)

const (
    host     = "localhost"
    port     = 5432
    user     = "postgres"
    password = "password"
    dbname   = "sampledb"
)

/*-------------------------------------------*\
||                Functions                  ||
\*-------------------------------------------*/
// Error Checking Fn
func CheckError(err error, str string) {
    if err != nil {
        fmt.Printf("Error @ : %s\n", str)
        panic(err)
    }
}

/*-------------------------------------------*\
||                 Main()                    ||
\*-------------------------------------------*/

func main() {
    // Open DB Conn
    psqlconn := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=disable", host, port, user, password, dbname)
    // sql.Register("postgres", &pq.Driver{})
    fmt.Printf(":: Drivers ::\n%s\n", sql.Drivers())
    db, err := sqlx.Connect("postgres", psqlconn)
    CheckError(err, "Main: sqlx.connect")
    defer db.Close()
}

Error – w/o sql.Register

$ go run name-generator.go 
:: Drivers ::
[]
Error @ : Main: sqlx.connect
panic: sql: unknown driver "postgres" (forgotten import?)

goroutine 1 [running]:
main.CheckError({0xc84320, 0xc000056680}, {0xc6073f, 0x5})
        C:/path/to/program.go:26 +0xa7    <--- Func CheckError(): panic(err)
main.main()
        C:/path/to/program.go:40 +0x125   <--- Func Main(): CheckError()
exit status 2

Code – w/ sql.Register

package main

import (
    "fmt"

    "database/sql"

    "github.com/jmoiron/sqlx"
    "github.com/lib/pq"
)

const (
    host     = "localhost"
    port     = 5432
    user     = "postgres"
    password = "password"
    dbname   = "sampledb"
)

/*-------------------------------------------*\
||                Functions                  ||
\*-------------------------------------------*/
// Error Checking Fn
func CheckError(err error, str string) {
    if err != nil {
        fmt.Printf("Error @ : %s\n", str)
        panic(err)
    }
}

/*-------------------------------------------*\
||                 Main()                    ||
\*-------------------------------------------*/

func main() {
    // Open DB Conn
    psqlconn := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=disable", host, port, user, password, dbname)
    sql.Register("postgres", &pq.Driver{})
    fmt.Printf(":: Drivers ::\n%s\n", sql.Drivers())
    db, err := sqlx.Connect("postgres", psqlconn)
    CheckError(err, "Main: sqlx.connect")
    defer db.Close()
}

Error – w/ sql.Register

$ go run name-generator.go 
panic: sql: Register called twice for driver postgres

goroutine 1 [running]:
database/sql.Register({0xa98bc9, 0x8}, {0xae6680, 0xc8a950})
        C:/Program Files/Go/src/database/sql/sql.go:51 +0x13d
main.main()
        C:/path/to/program.go:38 +0x11b
exit status 2

Additional Resources

  • Similar issue, but doesn’t solve my problem Link
  • SQLX Documentation Link
  • SQL Documentation Link

Solution

The package github.com/lib/pq registers it’s driver in an init function.

Remove the direct call to register the driver from the application:

 sql.Register("postgres", &pq.Driver{}) <-- delete this line

Import github.com/lib/pq for the side effect of executing the init() function:

package main

import (
    "fmt"
    "database/sql"
    "github.com/jmoiron/sqlx"
     _ "github.com/lib/pq"  // <-- add this line
)

Answered By – Bayta Darell

Answer Checked By – Katrina (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.