Gorm not reading columns on select - postgresql

I'm running a SELECT using WHERE on gorm but the results are comming with the columns store_name and type empty(""). I have the following struct on Go:
type Store struct {
ID uint
StoreName string
Type string
Code string `gorm:"unique"`
Active bool
CreatedAt *time.Time
UpdatedAt *time.Time
}
The following database on Postgres:
CREATE TABLE IF NOT EXISTS stores
(
id BIGSERIAL PRIMARY KEY,
store_name TEXT NOT NULL,
type TEXT NOT NULL,
code TEXT NOT NULL UNIQUE,
active BOOLEAN DEFAULT true,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ
);
Im running this select right here:
var store Store
result := db.First(&stores).Where("code = ?", code)
if err := result.Error; err != nil {
return nil, err
}
return &stores, nil
Does anyone know what I may be doing wrong? All columns are returned on the SELECT except for the columns StoreName and Type. Thank you so much in advance!

You need to set the field tag if field name differs from DB column name.
Example:
StoreName string `gorm:"column:store_name"`
See this document: https://gorm.io/docs/models.html

Related

Correct way to access data from postgresql using go-pgsql in GoLang

I've been reading the GoLang go-pgsql documentation in order to figure out how to access data with nested objects, but I have so far been unsuccessful.
Here's the description of what I am trying to achieve:
I have two models ClimateQuestions and Steps:
type ClimateQuestions struct {
tableName struct{} `pg:"climatequestions"`
Id int `json:"id" pg:",pk"`
Title string `json:"title"`
Steps []*Steps `pg:"rel:has-many"`
}
type Steps struct {
tableName struct{} `pg:"steps"`
Id int `json:"id"`
Label string `json:"label"`
Number int `json:"number"`
QuestionId int `json:"question_id"`
}
and here is how they're defined in the database:
CREATE TABLE climatequestions (
id SERIAL PRIMARY KEY,
title VARCHAR(255) NOT NULL
);
CREATE TABLE steps (
id SERIAL PRIMARY KEY,
title VARCHAR(255) NOT NULL,
value DOUBLE PRECISION NOT NULL,
question_id INT REFERENCES climatequestions(id)
);
And a relationship between these models is this: For every climate question, there can be many steps. I have denoted this by adding a field in ClimateQuestions struct called Steps with rel:has-many.
Now, from the database, I would like to obtain all the climate questions, and within each of them, I want an array of steps data.
My first method to achieve this has been the following:
var climateQuestions []model.ClimateQuestions
err := db.Model(&climateQuestions).Select()
This partially works in that it returns all the data relevant for climate questions, but it does not add the nested steps data. Here is the JSON format of what is returned:
[{"id":1,"title":"first question?","Steps":null},{"id":2,"title":"second question?","Steps":null}]
Any ideas as to how I may achieve this?
Because you have custom join foreign key, you need to add tag pg:"rel:has-many,join_fk:question_id" in ClimateQuestions.Steps
In struct Steps, you need to tell pg which field it is.
You forgot to call Relation function
this is the correct struct
type ClimateQuestions struct {
tableName struct{} `pg:"climatequestions"`
Id int `json:"id" pg:",pk"`
Title string `json:"title"`
Steps []*Steps `pg:"rel:has-many,join_fk:question_id"`
}
type Steps struct {
tableName struct{} `pg:"steps"`
Id int `json:"id"`
Label string `json:"label" pg:"title"`
Number int `json:"number" pg:"value"`
QuestionId int `json:"question_id"`
}
this is how you should exec db.
var climateQuestions []ClimateQuestions
err := db.Model(&climateQuestions).Relation("Steps").Select()
if err != nil {
panic(err.Error())
}
for _, v := range climateQuestions {
fmt.Printf("%#v\n", v)
for _, v1 := range v.Steps {
fmt.Printf("%#v\n", v1)
}
fmt.Println("")
}

sql: Scan error on column index 1, name "u.duration": converting driver.Value type []uint8 ("MORE") to a int: invalid syntax

I have enum filed in the table. When I do a SELECT query with the help of Select() method, I get:
sql: Scan error on column index 1, name "u.duration": converting driver.Value type []uint8 ("MORE") to a int: invalid syntax
my DB structure
CREATE TYPE duration_type AS ENUM ('TWO_MONTHS', 'SIX_MONTHS', 'ONE_YEAR','MORE');
CREATE TABLE shake_hands
(
id uuid,
duration duration_type NOT NULL,
phone_number TEXT,
email_address TEXT,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id)
);
my structs
type DurationType int
type ShakesHands struct {
ID uuid.UUID `db:"id"`
PhoneNumber string `db:"phone_number"`
Duration DurationType
Email *string `db:"email_address"`
ModelIds []string
}
Anything else need to be pasted here?

Using go's sqlx to insert record in postgres table with automatic ID generation

I am using sqlx to create a go api.
I want to insert a record in a table named day.
The corresponding go struct is the following
type Day struct {
ID string `db:"id" json:"id"`
Dateday string `db:"dateday" json:"dateday"`
Nameday string `db:"nameday" json:"nameday"`
Holyday bool `db:"holyday" json:"holyday"`
}
In an endpoint for Day creation, will be receiving all fields but the ID via a post request
What method should I use to interact with my db so as to:
a) create the record
b) not need to pass the ID myself and instruct postgres to auto-generate the field.
The table creation statement is the following:
CREATE TABLE IF NOT EXISTS "day" (
"id" SERIAL PRIMARY KEY,
"dateday" date NOT NULL,
"nameday" varchar(10) NOT NULL,
"holyday" boolean NOT NULL
);
I would suggest to override the MarshalJSON method as mentioned below:
func (r Day) MarshalJSON() ([]byte, error) {
root := make(map[string]interface{})
root["dateday"] = r.Dateday
root["nameday"] = r.Nameday
root["holyday"] = r.Holyday
return json.Marshal(root)
}
Ref: https://golang.org/pkg/encoding/json/#example__customMarshalJSON

Using DEFAULT keyword in Postgres

I use this library https://github.com/go-pg/pg .
I have a simple model.
type ChatAdmin struct {
Id int64
TgId int
CreatedAt time.Time `pg:"default:now()"`
}
With this code I'm trying to insert an instance to the table.
func (m Model) createChatAdminByTgUserID(tgUserId int) (ChatAdmin, error) {
admin := new(ChatAdmin)
admin.TgId = tgUserId
_, err := db.Model(admin).SelectOrInsert(admin)
return *admin, err
}
After insert, I see row in table where created_at == NULL.
Why does default:now() not working?
I've tried to set it with sql:"default:now()" but it did no helped.
My PostgreSQL version is: 11.66 running on Ubuntu
This is CREATE TABLE log:
"chat_admins" ("id" bigserial, "tg_id" bigint, "created_at" timestamptz NOT NULL DEFAULT now(), PRIMARY KEY ("id"))
This is from heroku dataclips after inserting:

Sqlx Get with prepared statements

I am trying to fetch some data from postgress table using prepared statements
If I try with database.Get() everything is returned.
Table:
create table accounts
(
id bigserial not null
constraint accounts_pkey
primary key,
identificator text not null,
password text not null,
salt text not null,
type smallint not null,
level smallint not null,
created_at timestamp not null,
updated timestamp not null,
expiry_date timestamp,
qr_key text
);
Account struct:
type Account struct {
ID string `db:"id"`
Identificator string `db:"identificator"`
Password string `db:"password"`
Salt string `db:"salt"`
Type int `db:"type"`
Level int `db:"level"`
ExpiryDate time.Time `db:"expiry_date"`
CreatedAt time.Time `db:"created_at"`
UpdateAt time.Time `db:"updated_at"`
QrKey sql.NullString `db:"qr_key"`
}
BTW i tried using ? instead of $1 & $2
stmt, err := database.Preparex(`SELECT * FROM accounts where identificator = $1 and type = $2`)
if err != nil {
panic(err)
}
accounts := []account.Account{}
err = stmt.Get(&accounts, "asd", 123)
if err != nil {
panic(err)
}
The error I get is
"errorMessage": "scannable dest type slice with \u003e1 columns (10) in result",
In the table there are no records I tried to remove all fields except the ID from Account (struct), however it does not work.
Documentation for sqlx described Get and Select as:
Get and Select use rows.Scan on scannable types and rows.StructScan on
non-scannable types. They are roughly analagous to QueryRow and Query,
where Get is useful for fetching a single result and scanning it, and
Select is useful for fetching a slice of results:
For fetching a single record use Get.
stmt, err := database.Preparex(`SELECT * FROM accounts where identificator = $1 and type = $2`)
var account Account
err = stmt.Get(&account, "asd", 123)
If your query returns more than a single record use Select with statement as:
stmt, err := database.Preparex(`SELECT * FROM accounts where identificator = $1 and type = $2`)
var accounts []Account
err = stmt.Select(&accounts, "asd", 123)
In your case if you use stmt.Select instead if stmt.Get. It will work.