在gorm

时间:2018-01-26 11:27:50

标签: postgresql go go-gorm

我有两个结构:

type GoogleAccount struct {
     Id     uint64
     Token  string
}

它代表我的自定义PostgreSQL对象类型(我自己创建):

CREATE TYPE GOOGLE_ACCOUNT AS
(
  id    NUMERIC,
  token TEXT
);

下一个结构是DB中的表:

type Client struct {
     IdClient       uint64          `gorm:"primary_key"`
     Name           string
     PhotoUrl       string
     ApprovalNumber uint16
     Phone          string
     Password       string
     HoursOfNotice  int8
     Google         GoogleAccount
}

我的自定义对象嵌套在Client类型中,并命名为google。我试图通过下一种方式读取数据:

var users model.Client
db.First(&users)

但遗憾的是,我无法读取字段google(具有默认值)。我不想用google_account创建单独的表,或者将此结构作为客户端表中的单独字段或将其打包为json(创建单独的实体,因为此结构不仅用于此表,而且我在搜索中新的方式,得到相同的结果,但更优雅)。任务不是为了简化表格中的数据表示。我需要将对象的正确映射从postgres到实体。

现在我找到了一个解决方案 - 将Scanner实施到GoogleAccount。但是输入法中的值是[] uint8。我可以假设,[] uint8可以转换为字符串,之后我可以解析这个字符串。这个字符串(保存在db中)看起来像(x,x) - 其中x - 是值。是正确的方法,解析字符串并将值设置为对象?或者是通过ORM获得此结果的方法?

是否有可能将这些数据作为嵌套结构对象读取?

2 个答案:

答案 0 :(得分:2)

看起来你想要用你拥有的东西做两件事:(1)更新模型以便你有正确的关系绑定,(2)如果你正在尝试使用.Preload()方法让它在阅读时关联数据。

模型更改

Gorm根据结构中属性的名称和引用结构的名称自动推断关系。问题是类型Google的{​​{1}}属性没有关联,因为gorm正在寻找GoogleAccount

您还错过type Google struct上的外键。 ORM如何知道哪个GoogleAccount与哪个GoogleAccount相关联?您应该在Client结构定义中添加ClientId

另外,我会更改你用来键入GoogleAccount的主键,因为这是gorm默认的(除非你有充分的理由不使用它)

如果我是你,我会将结构定义更改为以下内容:

uint

有关此问题的更多信息,请查看此处的协会文档:http://gorm.io/associations.html#has-one

预加载关联

现在您实际上已经正确关联它们,您可以type Client struct { IdClient uint `gorm:"primary_key"` Name string PhotoUrl string ApprovalNumber uint16 Phone string Password string HoursOfNotice int8 GoogleAccount GoogleAccount // Change this to `GoogleAccount`, the same name of your struct } type GoogleAccount struct { Id uint ClientId uint // Foreign key Token string } 获取所需的嵌套对象:

.Preload()

使用db.Preload("GoogleAccount").First(&user) 会根据.Preload()使用正确关联的user.GoogleAccount填充GoogleAccount属性。

有关此内容的更多信息,请查看预加载文档:http://gorm.io/crud.html#preloading-eager-loading

答案 1 :(得分:1)

现在我找到了一个解决方案 - 将扫描程序实施到smtpable_type。在输入GoogleAccount方法时,我得到了Scan,我将其转换为字符串并在最后进行解析。此字符串(保留在db中)看起来像[]uint8 - 其中(x,x) - 是值。当然,这不是实现我的目标的正确方法。但我无法找到其他解决方案。

强烈推荐通过关系使用经典绑定或简单地将表中的这些字段保存为最简单的值(而不是对象)。

但是如果你想在表中试验嵌套对象,你可以看看我的实现,也许它对你有用:https://github.com/kirikzyusko1996/go-cleaning-api/blob/master/src/app/model/client.go