3

I'm using go 1.10.3 and I'm trying to use the sqlx package to get one row and enter it to a struct with Get(), or get several rows and enter them to a slice with Select().

lets start with getting one row into a struct.

I created the following struct:

type PsqlProduct struct {
    Id              int64          `db:"product_id"`
    Name            string         `db:"product_name"`
    Desc            sql.NullString `db:"product_desc"`
    YearManufacture sql.NullInt64  `db:"year_manufacture"`
    Quantity        sql.NullInt64  `db:"quantity"`
}

for the query:

QUERY_SELECT_PRODUCT = `select wd.product.id as product_id,
trans_p_name.text as product_name,
trans_p_desc.text as product_desc,
wd.product.year_manufacture, wd.product.quantity
from wd.product
join wd.text_translation as trans_p_name 
    on trans_p_name.text_id = wd.product.product_name_trans_id and trans_p_name.lang_id=1
left join wd.text_translation as trans_p_desc 
    on trans_p_desc.text_id = wd.product.product_desc_trans_id and trans_p_desc.lang_id=1
where wd.product.id = $1 
`

and I created the following function to get product by id:

func PsqlGetProductById(productId int) *Product {
    product := new(PsqlProduct)
    err := Psqldb.Get(&product, QUERY_SELECT_PRODUCT,productId)
    if err != nil {
        log.Fatalf("error: %v",err)
        return nil
    } else {

        newp := Product{
            ID:   uint(product.Id),
            Name: product.Name,
        }
        if product.Quantity.Valid {
            newp.Quantity = uint16(product.Quantity.Int64)
        }
        if product.YearManufacture.Valid {
            newp.YearManufacture = uint16(product.YearManufacture.Int64)
        }
        if product.Desc.Valid {
            newp.Desc = product.Desc.String
        }
        return &newp
    }
}

and I got the error

error: scannable dest type ptr with >1 columns (5) in result

it's as if Get() function is only for one column.. but the documentation clearly states it's not!

if I change the Get() function call to Psqldb.QueryRowx(QUERY_SELECT_PRODUCT, productId).StructScan(product)

then it does work.. but still.. trying to find out why Get() doesn't work.

next.. Select()

so this is the struct

type PsqlCategory struct {
    Id               int64         `db:"category_id"`
    Name             string        `db:"category_name"`
    ParentCategoryId sql.NullInt64 `db:"parent_category_id"`
}

sql query:

QUERY_SELECT_CATEGORIES = `
select category.id as category_id,
       text_translation.text as category_name,
       category.parent_category_id
from category
join text_translation on text_translation.text_id=category.category_name_trans_id
and text_translation.lang_id = 1`

and the function

func PsqlGetCategories() []Category {
    categories := []PsqlCategory{}
    err := Psqldb.Select(&categories, QUERY_SELECT_CATEGORIES)
    if err != nil {
        log.Fatalf("could not parse categories: %v", err)
        return nil
    }
    var nCategories []Category
    for _, cat := range categories {
        newCat := Category{
            Id:   cat.Id,
            Name: cat.Name,
        }
        if cat.ParentCategoryId.Valid {
            newCat.ParentCategoryId = cat.ParentCategoryId.Int64
        }
        nCategories = append(nCategories, newCat)
    }
    return nCategories
}

and this is the error

could not parse categories: pq: relation "category" does not exist

it's like I totally misunderstood the usage of the sqlx library or I'm missing something..

any information regarding the issue would be greatly appreciated.

4
  • Second one is coming from postgreSQL saying relation "category" does not exist. Commented Aug 25, 2018 at 15:40
  • @CetinBasoz - yay thanks! adding the name of the schema helped there. still trying to figure out why Get() doesn't work the way it should Commented Aug 25, 2018 at 17:17
  • 1
    You're passing in a "pointer to a pointer to a struct". Change Psqldb.Get(&product, QUE... to Psqldb.Get(product, QUE. product is already a pointer because that's what new returns. Commented Aug 25, 2018 at 17:58
  • @mkopriva - yay thanks. that's resolved my problem. please post it as an answer Commented Aug 25, 2018 at 18:03

2 Answers 2

5

The problem arises because you're passing **PsqlProduct to Get which thinks that you want to scan the query result into the pointed to pointer, hence "... dest type ptr with >1 columns ...".

Just change:

err := Psqldb.Get(&product, QUERY_SELECT_PRODUCT,productId)

to:

err := Psqldb.Get(product, QUERY_SELECT_PRODUCT,productId)
Sign up to request clarification or add additional context in comments.

Comments

0

For it works with Sqlx - when SelectContext It is used when you expect an array of data, For single row data use GetContext

users :=  &[]datamodel.User{}
`Select id, name, code from users where company_id=`
r.db.SelectContext(ctx, users, query, companyID)

In the above example, I expect multiple users. The error was coming to me when I used GetContext

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.