Управлять структурой с помощью указателей из Gorm in Go? - PullRequest
0 голосов
/ 01 октября 2019

Я занимаюсь разработкой веб-сервера, написанного на Go, с использованием Gqlgen и Gorm (postgres диалект).

Я начал с описания модели моего пользователя:

# dbm.User{}

type User struct {
    BaseModel      
    Email       string  `gorm:"not null;unique_index:idx_email"`
    UserID      *string // External user ID
    Name        *string
    NickName    *string
    FirstName   *string
    LastName    *string
    Location    *string `gorm:"size:1048"`
    Description *string `gorm:"size:1048"`
}

В этом случае, насколько я понимаю, приятно использовать указатели для определенных значений в моей структуре, потому что они могут оцениватьдо <nil>, когда к нему не прикреплено значение. Принимая во внимание, что если я не использую указатели, int будет 0, если к нему не прикреплено значение. Хорошо, это имеет смысл ... если я не ошибаюсь ...

Однако сейчас я сталкиваюсь с трудностью при получении этого значения из операции Gorm на БД:

dbRecord := &dbm.User{}

db = db.Where(whereEmail, email).Find(&dbRecord)
fmt.Println("dbRecord:", dbRecord)
// Prints:
// dbRecord: &{{def90b3c-93ff-40f0-8d33-6320dddbe3f2 2019-10-01 14:16:34.365395 +0200 CEST 2019-10-01 14:16:34.365395 +0200 CEST} test@test.com <nil> 0xc0000a1cb0 0xc0000a1cd0 0xc0000a1cc0 <nil> 0xc0000a1cf0 0xc0000a1ce0}

Этот код запрашивает пользователя, у которого адрес электронной почты «email@email.com», и, очевидно, некоторые поля в структуре указывают на фактический адрес значения. Это имеет смысл, но это очень раздражает, если я хочу прочитать эти данные. Есть ли обычный способ чтения этих данных?

Я пытался преобразовать эту структуру в структуру GQL (которая была автоматически сгенерирована GQLgen):

# gqlm.User{}

type User struct {
    ID          string     `json:"id"`
    Email       string     `json:"email"`
    UserID      *string    `json:"userId"`
    Name        *string    `json:"name"`
    FirstName   *string    `json:"firstName"`
    LastName    *string    `json:"lastName"`
    NickName    *string    `json:"nickName"`
    Description *string    `json:"description"`
    Location    *string    `json:"location"`
    CreatedAt   time.Time  `json:"createdAt"`
    UpdatedAt   *time.Time `json:"updatedAt"`
}

Но опять же,Я получаю адреса, когда мне нужны значения, что имеет смысл.

Поэтому единственный способ, который я нашел, - это создать новую пользовательскую структуру customUser, маршалировать данные из Gorm, а затем распаковать их в мою структуру customUser:

type customUser struct {
    ID          string    `json:"id"`
    Email       string    `json:"email"`
    UserID      string    `json:"userId"`
    Name        string    `json:"name"`
    FirstName   string    `json:"firstName"`
    LastName    string    `json:"lastName"`
    NickName    string    `json:"nickName"`
    Description string    `json:"description"`
    Location    string    `json:"location"`
    CreatedAt   time.Time `json:"createdAt"`
    UpdatedAt   time.Time `json:"updatedAt"`
}

bs, _ := json.Marshal(record)
var s = string(bs)

newRecord := &customUser{}
bs = []byte(s) // This is maybe not necessary

err = json.Unmarshal(bs, newRecord)
if err != nil {
   fmt.Println(err)
}

fmt.Printf("record: %+v\n", newRecord)
// I now get the right format: record: &{ID:def90b3c-93ff-40f0-8d33-6320dddbe3f2 Email:test@test.com UserID: Name:frer FirstName:fwef LastName: NickName:trgt Description:werfergh rthrt hr Location:wfwf CreatedAt:2019-10-01 14:16:34.365395 +0200 CEST UpdatedAt:2019-10-01 14:16:34.365395 +0200 CEST}

Но это кажется излишним и требует больших усилий, если мне нужно создавать такую ​​структуру каждый раз, когда мне нужно читать данные из БД. Это путь? Или вы знаете более удобный способ?

1 Ответ

0 голосов
/ 08 октября 2019

Вам нужно использовать sql.NullString для типов строковых указателей.

Пожалуйста, смотрите https://golang.org/pkg/database/sql/#NullString

В частности, используются sql нулевые типы, где имеет смысл иметь понятие "недопустимое значение для этого поля ".

...