How do I connect to postgresql with gorm? - go

How do I connect to postgresql with gorm? (FATAL: password authentication failed for user "postgres" (SQLSTATE 28P01))
package model
import (
"gorm.io/driver/postgres"
"gorm.io/gorm"
)
var db *gorm.DB
func init() {
var err error
dsn := "host=localhost user=postgres dbname=postgres port=5432 sslmode=disable TimeZone=Asia/Tokyo"
db, err = gorm.Open(postgres.Open(dsn), &gorm.Config{})
if err != nil {
panic("failed to connect database")
}
db.AutoMigrate(&User{})
db.AutoMigrate(&Todo{})
}

you can try this instead : Use Sprintf to declare dsn
host := "localhost"
user := "postgres"
password := ""
dbname := "DBNAME"
port := "5432"
dsn := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%s sslmode=disable",
host, user, password, dbname, port)
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{
SkipDefaultTransaction: true,
})
if err != nil {
panic(err)
}
and check the database connection use :
func TestConnect(t *testing.T) {
//your DB setup function
}

Related

Unable to connect to Dremio with ODBC in Golang

I am new to Golang and I am trying to connect to Dremio using ODBC in Golang with Dremio host, port, username and password. The following code gives me error
2022/04/19 17:36:42 missing username and password
exit status 1
import (
"database/sql"
"fmt"
"gographqlservice/graph/model"
"log"
_ "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) {
drminfo := fmt.Sprintf("host=%s port=%d user=%s password=%s sslmode=disable",
host, port, user, password)
db, err := sql.Open("dremio", drminfo)
if err != nil {
log.Fatal("error occurred")
log.Fatal(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() {
// some code goes here
}
err = rows.Err()
if err != nil {
log.Fatal(err)
}
defer db.Close()
return &asset, err
}
It looks like you are using driver code from "Pinpoint" that is documented here:
https://pkg.go.dev/github.com/pinpt/go-dremio#section-readme
You can see their connection string should be in the following form:
db, err := sql.Open("dremio", "https://user:pass#dremio.example.com")
Your code appears to be in the form:
drminfo := fmt.Sprintf("host=%s port=%d user=%s password=%s sslmode=disable",
host, port, user, password)
To allow the Pinpoint code to parse this connection string and pull out the user and password, try the following instead:
drminfo := fmt.Sprintf("http://%s:%s#%s",
user, password, host)
The error message you're seeing comes from the following line in the Pinpoint code. In this case, it means they were not able to figure out the user name from the connection string provided.
https://github.com/pinpt/go-dremio/blob/master/driver/driver.go#L187
if u.User == nil {
return nil, fmt.Errorf("missing username and password")
}

Why am I getting a timeout when executing a query against an Aurora Serverless instance from a Go lambda

This is my first attempt at using a lambda with Aurora Serverless(postgres). I wrote some code to essentially be able to check that the connection is working, but it's not clear to me why I am getting a timeout when I try to execute the query.
This code seems pretty straightforward. Is there something I'm missing about the serverless environment?
func connect() (*sql.DB, error) {
dbName := "my_db"
dbUser := "app_user"
dbHost := "REDACTED.us-east-2.rds.amazonaws.com"
dbPort := 5432
dbEndPoint := fmt.Sprintf("%s:%d", dbHost,dbPort)
region := "us-east-2"
creds := credentials.NewEnvCredentials()
authToken, err := rdsutils.BuildAuthToken(dbEndPoint, region, dbUser, creds)
if err != nil {
fmt.Printf("ERROR: %v \n", err)
return nil, err
}
dsn := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s \n",
dbHost, dbPort, dbUser, authToken, dbName,
)
return sql.Open("postgres", dsn)
}
func Healthcheck() (bool, error) {
db, err := connect()
if err != nil {
return false, err
}
defer db.Close()
var result int
err = db.QueryRow("Select 1").Scan(&result)
if err != nil {
return false, err
}
fmt.Printf("Result: %v\n", result)
return true, nil
}

Go expected identifier on left side of :=syntax

Hello I am trying to make a connection to postgres using go, but I have the following error:
on this line :
conn.pool, err := sql.Open("postgres", uri)
err:
expected identifier on left side of :=syntax
I'm new to go and I don't know why and how to resolve this error, if someone can help me where I'm going wrong.
package database
import (
"database/sql"
"fmt"
"log"
"os"
"strconv"
)
type Db struct {
pool *sql.DB
}
type Connection interface {
Close()
DB() *sql.DB
}
func NewPostgreSQLsql() (Connection, error) {
var conn Db
uri := getURI()
conn.pool, err := sql.Open("postgres", uri)
if err != nil {
log.Fatal(err.Error())
return nil, err
}
if err := conn.Ping(); err != nil {
log.Fatal(err.Error())
return nil, err
}
return &conn, nil
}
func (c *db) DB() *sql.DB {
return c.pool
}
func (c *Db) Close() {
c.pool.Close()
}
func getURI() string {
dbPort, err := strconv.Atoi(os.Getenv("DB_PORT"))
if err != nil {
log.Println("error on load db port from env:", err.Error())
dbPort = 5432
}
return fmt.Sprintf(os.Getenv("DB_HOST"),
dbPort,
os.Getenv("DB_USER"),
os.Getenv("DB_NAME"),
os.Getenv("DB_PASSWORD"))
}
you cannot directly initialize and assign to conn.pool with :=
and you should initialize conn object
Try this
conn := Db{}
uri := getURI()
pool, err := sql.Open("postgres", uri)
conn.pool = pool
or
uri := getURI()
pool, err := sql.Open("postgres", uri)
conn := Db{pool}

How to create a Postgres database using GORM

This is primarily focused towards having setup() and teardown() methods for a test suite that I'm planning on writing that involves creation of a DB.
I've figured out how to create a DB using GORM. However, I'm not sure if this is the best approach.
package main
import (
"fmt"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/postgres"
"log"
)
func main() {
db, err := gorm.Open("postgres", "host=127.0.0.1 port=5432 user=superuser dbname=postgres password='' sslmode=disable")
capture(err)
db = db.Exec("CREATE DATABASE test_db;")
if db.Error != nil {
fmt.Println("Unable to create DB test_db, attempting to connect assuming it exists...")
db, err = gorm.Open("postgres", "host=127.0.0.1 port=5432 user=superuser dbname=test_db password='' sslmode=disable")
if err != nil {
fmt.Println("Unable to connect to test_db")
capture(err)
}
}
defer db.Close()
}
func capture(err error) {
if err != nil {
log.Fatalf("%s", err)
}
}
I'm connecting to the default postgres DB first, after which I'm creating a second test DB which I'm planning on using.
Is this the best approach ? Or is there a way to connect to Postgres without having a pre-existing DB.
NOTE: I've already looked up answers where people have used SQL driver to connect to a DB using only the connection string user:password#/. That has not worked in my case.(like here)
I've alse tried a connection string without having a DB name, that results in the driver trying to connect to a DB with the same name as the user. Which fails since such a DB does not exist.
The way I went about it was to avoid creating the db first with the expectation of an error and then using that as an indication db already exists. I find below to be more graceful IMO. This is with using GORM btw
connStr := fmt.Sprintf("user=%s password=%s host=%s port=%s dbname=%s sslmode=disable",
"user",
"password",
"host",
"port",
"postgres")
// connect to the postgres db just to be able to run the create db statement
db, err := gorm.Open(postgres.Open(connStr), &gorm.Config{
Logger: logger.Default.LogMode(logger.Silent)})
if err != nil {
return err
}
// check if db exists
stmt := fmt.Sprintf("SELECT * FROM pg_database WHERE datname = '%s';", client.Name)
rs := db.Raw(stmt)
if rs.Error != nil {
return rs.Error
}
// if not create it
var rec = make(map[string]interface{})
if rs.Find(rec); len(rec) == 0 {
stmt := fmt.Sprintf("CREATE DATABASE %s;", dbName)
if rs := db.Exec(stmt); rs.Error != nil {
return rs.Error
}
// close db connection
sql, err := db.DB()
defer func() {
_ = sql.Close()
}()
if err != nil {
return err
}
}
Here is how I achieved creating a postgreSQL database using Gorm, the key is to connect to postgreSQL only, a connection to "database" is not required to create a database, only connecting to database engine is enough. Just don't pass the database base in connection string.
In main.go
package main
import (
"gorm.io/driver/postgres"
"gorm.io/gorm"
"fmt"
"github.com/joho/godotenv"
)
func createDatabase() {
dsn := fmt.Sprintf("host=%s port=%s user=%s password=%s sslmode=disable TimeZone=%s", Config("DB_HOST"), Config("DB_PORT"), Config("DB_USER"), Config("DB_PASSWORD"), Config("DB_TIMEZONE"))
DB, _ := gorm.Open(postgres.Open(dsn), &gorm.Config{})
createDatabaseCommand := fmt.Sprintf("CREATE DATABASE %s", Config("DB_NAME"))
DB.Exec(createDatabaseCommand)
}
func main() {
createDatabase()
}
Now simply just run go get -d ./... && go run main.go
Your method seems valid enough. You could also use postgres' createdb utility to create the DB before you connect to it. For example:
import (
"log"
"os/exec"
"bytes"
)
func createPgDb() {
cmd := exec.Command("createdb", "-p", "5432", "-h", "127.0.0.1", "-U", "superuser", "-e", "test_db")
var out bytes.Buffer
cmd.Stdout = &out
if err := cmd.Run(); err != nil {
log.Printf("Error: %v", err)
}
log.Printf("Output: %q\n", out.String())
}
This example is paraphrased from the Command / Run examples in the Go manual https://golang.org/pkg/os/exec/#Command
I suggest using database/psql package for creating the database , not gorm
be sure you imported these packages
import (
"database/sql"
"fmt"
_ "github.com/lib/pq"
)
and use below codes to create database
url := fmt.Sprintf("host=%s port=%s user=%s password=%s sslmode=disable",
DBHost, DBPort, DBUsername, DBPassword)
db, err := sql.Open("postgres", url)
if err != nil {
panic(err)
}
defer db.Close()
_, err = db.Exec(fmt.Sprintf("CREATE DATABASE %s;", DBName))
if err != nil {
panic(err)
}

CRUD operations on Redshift databases using Golang

Could you please give me some explanations and some code examples on how it would be done (ex: creating tables and inserting data) ?
Which library would you advise me to use ?
Thanks !
Please note the side-effect import of github.com/lib/pq
After this queries can be run by db.Query() or db.Exec()
https://golang.org/pkg/database/sql/#example_DB_Query
https://golang.org/pkg/database/sql/#pkg-examples
import (
_ "github.com/lib/pq"
"database/sql"
"fmt"
)
func MakeRedshfitConnection(username, password, host, port, dbName string) (*sql.DB, error) {
url := fmt.Sprintf("sslmode=require user=%v password=%v host=%v port=%v dbname=%v",
username,
password,
host,
port,
dbName)
var err error
var db *sql.DB
if db, err = sql.Open("postgres", url); err != nil {
return nil, fmt.Errorf("redshift connect error : (%v)"), err
}
if err = db.Ping(); err != nil {
return nil, fmt.Errorf("redshift ping error : (%v)", err)
}
return db, nil
}

Resources