parsing - 从 yaml 到 go-gorm 的自引用 uuid
问题描述
我正在尝试从 yaml 文件创建一个自引用的 many2many。引用保存为 uuid,所以我试过这个:
type Activity struct {
ID uuid.UUID `yaml:"id" gorm:"type:uuid;primaryKey"`
ActivityStreamID uuid.UUID `yaml:"stream" gorm:"type:uuid"`
MaturityLevelID uuid.UUID `yaml:"level" gorm:"type:uuid"`
Title string `yaml:"title"`
Benefit string `yaml:"benefit"`
ShortDescription string `yaml:"shortDescription"`
LongDescription string `yaml:"longDescription" gorm:"type:text"`
Results StringArray `yaml:"results" gorm:"type:text[]"`
Metrics StringArray `yaml:"metrics" gorm:"type:text[]"`
Costs string `yaml:"costs"`
Personnel StringArray `yaml:"personnel" gorm:"type:text[]"`
Notes string `yaml:"notes"`
RelatedActivities []*Activities `yaml:"relatedActivities" gorm:"type:uuid;many2many:related_activities"`
Type string `yaml:"type"`
Questions []Question `gorm:"type:uuid;many2many:activity_questions;"`
}
问题是,虽然这看起来像是 go-gorm 的正确用法,但它并没有在 yaml 中正确解组:
2020/10/31 21:10:28 Problem unmarshaling example.yml: yaml: unmarshal errors:
line 47: cannot unmarshal !!str `e17d573...` into example.Activity
exit status 1
切换RelatedActivities
到 useuuid.UUID
时,yaml 工作正常,但在 go-gorm 中无法正确识别:
...
RelatedActivities []*uuid.UUID `yaml:"relatedActivities" gorm:"type:uuid;many2many:related_activities"`
...
我在这个例子中使用 sqlite:
2020/10/31 21:11:51 .../populateDB.go:60 row value misused
[0.063ms] [rows:0] INSERT INTO `activities` (`id`,`activity_stream_id`,`maturity_level_id`,`title`,`benefit`,`short_description`,`long_description`,`results`,`metrics`,`costs`,`personnel`,`notes`,`related_activities`,`type`,`questions`) VALUES ("a573c126-b3e3-45fb-a9d1-d94c8158cf60","1a7ad26d-9e48-411e-95a6-3be79e1b90ea","1cb6e197-ca82-45ec-a65b-0ecbdd784720","Enforce timely patch management","Clear view","Actively.....","Develop ...","{}","{}","","{}","",("93dff7be-5f95-4f8d-87d2-4f4261002508","2bf0e192-a904-444b-8a2f-38c33256e80a","0082a76b-1a37-44d9-ab04-43bd2168e13d"),"Activity",(NULL))
2020/10/31 21:11:51 row value misused
...
很明显,这是因为自引用是 中的一个列表("93dff7be-5f95-4f8d-87d2-4f4261002508","2bf0e192-a904-444b-8a2f-38c33256e80a","0082a76b-1a37-44d9-ab04-43bd2168e13d")
,但不是在新的 many2many 表中创建的。
接下来我应该尝试什么?
解决方案
好吧,这就是我最终做的事情:额外的间接级别。
没有指向[]*Activity
,而是添加了一个新RelatedActivity
的 uuid。
// Activity
type Activity struct {
ID uuid.UUID `yaml:"id" gorm:"type:uuid;primaryKey"`
ActivityStreamID uuid.UUID `yaml:"stream" gorm:"type:uuid"`
MaturityLevelID uuid.UUID `yaml:"level" gorm:"type:uuid"`
Title string `yaml:"title"`
Benefit string `yaml:"benefit"`
ShortDescription string `yaml:"shortDescription"`
LongDescription string `yaml:"longDescription" gorm:"type:text"`
Results StringArray `yaml:"results" gorm:"type:text[]"`
Metrics StringArray `yaml:"metrics" gorm:"type:text[]"`
Costs string `yaml:"costs"`
Personnel StringArray `yaml:"personnel" gorm:"type:text[]"`
Notes string `yaml:"notes"`
RelatedActivities []RelatedActivity `yaml:"relatedActivities" gorm:"many2many:linked_activities"`
Type string `yaml:"type"`
Questions []Question `gorm:"type:uuid;many2many:activity_questions;"`
}
type RelatedActivity struct {
ID uuid.UUID `yaml:"id" gorm:"type:uuid"`
}
还实现了UnmarshalYAML
type RelatedActivity
,如下所示:
// Implements the Unmarshaler interface of the yaml pkg.
func (r *RelatedActivity) UnmarshalYAML(unmarshal func(interface{}) error) error {
var myuuid uuid.UUID
err := unmarshal(&myuuid)
if err != nil {
return err
}
r.ID = myuuid
return nil
}
这在表中创建了正确的 many2many 关系linked_activities
:
sqlite> select * from linked_activities ;
27cdd2a3-36a4-4e56-a426-32c7a78fcf4f|e17d5735-1090-4f65-a1fe-6040b56ad0b1
1cc77725-cb23-49f3-9447-7838668f6184|e17d5735-1090-4f65-a1fe-6040b56ad0b1
93dff7be-5f95-4f8d-87d2-4f4261002508|921ff24f-0b9f-4df9-a512-9aa2f8a4a570
93dff7be-5f95-4f8d-87d2-4f4261002508|b3b20a75-740c-4880-a21a-d9aa0c1298c7
d1cb54f1-ddd3-4324-8051-3df320fc0ff8|93dff7be-5f95-4f8d-87d2-4f4261002508
2bf0e192-a904-444b-8a2f-38c33256e80a|00000000-0000-0000-0000-000000000000
15d73a64-818c-4301-9504-c8d938ca2434|2bf0e192-a904-444b-8a2f-38c33256e80a
15d73a64-818c-4301-9504-c8d938ca2434|c1aef013-7df1-400c-bdd3-c660b609b7b2
15d73a64-818c-4301-9504-c8d938ca2434|05073fb1-30c7-4143-a12a-6ba74a44c580
d955a7b3-fbfc-4b6a-a5b3-27af9e01c377|11dd0c95-f891-4b6c-b850-a27f0557a9dd
d955a7b3-fbfc-4b6a-a5b3-27af9e01c377|281369f4-91da-4d4c-84b0-729e344e2c93
d955a7b3-fbfc-4b6a-a5b3-27af9e01c377|05a3e75c-6c65-4ae5-8a11-5cbf4295662b
f2a309b8-2fbc-46cf-b2f1-1c9cde20dc0a|5bcb5237-5a0f-4085-bb12-266c9ecfa84d
f2a309b8-2fbc-46cf-b2f1-1c9cde20dc0a|4f6a0679-6d08-40de-bcc7-75ea1af65679
f2a309b8-2fbc-46cf-b2f1-1c9cde20dc0a|a395d699-17b9-47b2-8d59-95738d716283
bcc960e8-35aa-4ad5-8a9d-39a272cbf6f1|4f6a0679-6d08-40de-bcc7-75ea1af65679
我认为这应该由gorm处理,但至少它适用于我的情况。
推荐阅读
- python - 如何使用 tkinter 在 python 中选择多个文件或整个文件夹(显示它包含的所有文件的名称)?
- python - 用于抓取多个页面标题的 Python 问题
- python - 搜索栏带来空白结果页面
- jquery - 通过ajax刷新后重新绑定jquery插件
- r - 无法使用 ggPredict 可视化线性回归
- java - 如何在 IntelliJ 中将目录转换为包
- python - 使用 Plotly add_trace go.scatter for-loop 填充仅具有唯一跟踪名称的图例
- spring-boot - 使用 DiscoveryClient 读取 Eureka 服务器实例的问题
- python - 有没有办法从 PHP 7.4.7 调用 Python3 函数?
- python - 如何拆分数据集并将其与 LSTM seq2seq 模型一起使用?