简体   繁体   中英

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?

  1. Because you have custom join foreign key, you need to add tag pg:"rel:has-many,join_fk:question_id" in ClimateQuestions.Steps
  2. In struct Steps , you need to tell pg which field it is.
  3. 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("")
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM