我正在尝试从一个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当将yaml切换到使用uuid.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表中创建的。
下一步我应该尝试什么?
发布于 2020-11-28 22:47:47
好吧,这就是我最后要做的:一个额外的间接层。
没有指向[]*Activity,而是添加了一个仅包含uuid的新RelatedActivity。
// 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"`
}还实现了RelatedActivity类型的UnmarshalYAML,如下所示:
// 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
}在表linked_activities中创建了正确的many2many关系
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来处理,但至少它对我的情况有效。
https://stackoverflow.com/questions/64627600
复制相似问题