英文:
Gorm Joins not mapping to models
问题
我正在尝试通过使用SQL连接而不是Preload()来优化我的应用程序。
但是我遇到了一个问题,模型中的连接表始终为空。
我绝望地打开了一个新项目,并找到了一些简单的示例代码,但是问题依然存在。
如果你运行下面的代码,你会发现连接表始终是一个空数组。
我做错了什么吗?
import (
"fmt"
"log"
"github.com/jinzhu/gorm"
_ "github.com/lib/pq"
)
type Language struct {
ID uint `gorm:"primary_key"`
Name string
}
type Movie struct {
ID uint `gorm:"primary_key"`
Title string
Language Language
LanguageID uint
}
type Artist struct {
ID uint `gorm:"primary_key"`
Name string
Movies []Movie `gorm:"many2many:artist_movies"`
}
func createArtists() {
langs := []Language{{Name: "english"},
{Name: "tamil"},
{Name: "french"}}
for i, _ := range langs {
if err := db.Create(&langs[i]).Error; err != nil {
log.Fatal(err)
}
}
movies := []Movie{
{Title: "Nayagan", Language: langs[1]},
{Title: "Anbe sivam", Language: langs[1]},
{Title: "3 idiots", Language: langs[2]},
{Title: "Shamithab", Language: langs[2]},
{Title: "Dark Knight", Language: langs[0]},
{Title: "310 to Yuma", Language: langs[0]},
}
for i, _ := range movies {
if err := db.Create(&movies[i]).Error; err != nil {
log.Fatal(err)
}
}
artists := []Artist{
{Name: "Madhavan", Movies: []Movie{movies[1], movies[2]}},
{Name: "Kamal Hassan", Movies: []Movie{movies[0], movies[1]}},
{Name: "Dhanush", Movies: []Movie{movies[3]}},
{Name: "Aamir Khan", Movies: []Movie{movies[2]}},
{Name: "Amitabh Bachchan", Movies: []Movie{movies[3]}},
{Name: "Christian Bale", Movies: []Movie{movies[4], movies[5]}},
{Name: "Russell Crowe", Movies: []Movie{movies[5]}},
}
for i, _ := range artists {
if err := db.Create(&artists[i]).Error; err != nil {
log.Fatal(err)
}
}
}
var db *gorm.DB
func main() {
var err error
db, err = gorm.Open("postgres", "user=admin password=1234 dbname=test sslmode=disable")
if err != nil {
log.Fatal(err)
}
db.AutoMigrate(new(Language), new(Movie), new(Artist))
db.LogMode(true)
createArtists()
var artists []Artist
if err = db.Joins("JOIN artist_movies on artist_movies.artist_id=artists.id").
Joins("JOIN movies on movies.id=artist_movies.movie_id").
Joins("JOIN languages on movies.language_id=languages.id").
Where("languages.name=?", "tamil").
Group("artists.id").Find(&artists).Error; err != nil {
log.Fatal(err)
}
for _, ar := range artists {
fmt.Println(ar.Movies)
}
artists = []Artist{}
if err = db.Joins("JOIN artist_movies on artist_movies.artist_id=artists.id").
Joins("JOIN movies on artist_movies.movie_id=movies.id").Where("movies.title=?", "Nayagan").
Group("artists.id").Find(&artists).Error; err != nil {
log.Fatal(err)
}
for _, ar := range artists {
fmt.Println(ar.Movies)
}
artists = []Artist{}
if err = db.Joins("JOIN artist_movies on artist_movies.artist_id=artists.id").
Joins("JOIN movies on artist_movies.movie_id=movies.id").
Where("movies.title in (?)", []string{"3 idiots", "Shamitabh", "310 to Yuma"}).
Group("artists.id").Find(&artists).Error; err != nil {
log.Fatal(err)
}
for _, ar := range artists {
fmt.Println(ar.Movies)
}
}
英文:
I'm trying to optimize my app by using sql joins instead of Preload().
But i've ran into an issue where the joined table in the model is always empty.
In desperation i've opened a new project and found some simple sample code, and again the same problem.
If you run the code below you'll see that the joined table is always an empty array.
Am i doing something wrong?
import (
"fmt"
"log"
"github.com/jinzhu/gorm"
_ "github.com/lib/pq"
)
type Language struct {
ID uint `gorm:"primary_key"`
Name string
}
type Movie struct {
ID uint `gorm:"primary_key"`
Title string
Language Language
LanguageID uint
}
type Artist struct {
ID uint `gorm:"primary_key"`
Name string
Movies []Movie `gorm:"many2many:artist_movies"`
}
func createArtists() {
langs := []Language{{Name: "english"},
{Name: "tamil"},
{Name: "french"}}
for i, _ := range langs {
if err := db.Create(&langs[i]).Error; err != nil {
log.Fatal(err)
}
}
movies := []Movie{
{Title: "Nayagan", Language: langs[1]},
{Title: "Anbe sivam", Language: langs[1]},
{Title: "3 idiots", Language: langs[2]},
{Title: "Shamithab", Language: langs[2]},
{Title: "Dark Knight", Language: langs[0]},
{Title: "310 to Yuma", Language: langs[0]},
}
for i, _ := range movies {
if err := db.Create(&movies[i]).Error; err != nil {
log.Fatal(err)
}
}
artists := []Artist{
{Name: "Madhavan", Movies: []Movie{movies[1],movies[2]}},
{Name: "Kamal Hassan", Movies: []Movie{movies[0], movies[1]}},
{Name: "Dhanush", Movies: []Movie{movies[3]}},
{Name: "Aamir Khan", Movies: []Movie{movies[2]}},
{Name: "Amitabh Bachchan", Movies: []Movie{movies[3]}},
{Name: "Christian Bale", Movies: []Movie{movies[4], movies[5]}},
{Name: "Russell Crowe", Movies: []Movie{movies[5]}},
}
for i, _ := range artists {
if err := db.Create(&artists[i]).Error; err != nil {
log.Fatal(err)
}
}
}
var db *gorm.DB
func main() {
var err error
db, err = gorm.Open("postgres", "user=admin password=1234 dbname=test sslmode=disable")
if err != nil {
log.Fatal(err)
}
db.AutoMigrate(new(Language), new(Movie), new(Artist))
db.LogMode(true)
createArtists()
var artists []Artist
if err = db.Joins("JOIN artist_movies on artist_movies.artist_id=artists.id").
Joins("JOIN movies on movies.id=artist_movies.movie_id").
Joins("JOIN languages on movies.language_id=languages.id").
Where("languages.name=?", "tamil").
Group("artists.id").Find(&artists).Error; err != nil {
log.Fatal(err)
}
for _, ar := range artists {
fmt.Println(ar.Movies)
}
artists = []Artist{}
if err = db.Joins("JOIN artist_movies on artist_movies.artist_id=artists.id").
Joins("JOIN movies on artist_movies.movie_id=movies.id").Where("movies.title=?", "Nayagan").
Group("artists.id").Find(&artists).Error; err != nil {
log.Fatal(err)
}
for _, ar := range artists {
fmt.Println(ar.Movies)
}
artists = []Artist{}
if err = db.Joins("JOIN artist_movies on artist_movies.artist_id=artists.id").
Joins("JOIN movies on artist_movies.movie_id=movies.id").
Where("movies.title in (?)", []string{"3 idiots", "Shamitabh", "310 to Yuma"}).
Group("artists.id").Find(&artists).Error; err != nil {
log.Fatal(err)
}
for _, ar := range artists {
fmt.Println(ar.Movies)
}
}
答案1
得分: 1
Gorm不会自动加载相关表中的数据。你需要在查询中使用Preload("table")
来实现。在创建带有相关字段的记录时,可以使用关联。
文档:
Gorm目前不支持使用JOINS进行预加载,你需要使用SQL Builder创建SQL,并将结果的行映射到你的结构体中。
英文:
Gorm doesn't automatically load data into related tables. You have to use Preload("table")
for that in your query. When creating records with related fields, use associations.
Gorm doesn't currently support preloading with JOINS, you have to create SQL with SQL Builder and map the resulting rows
to your structures.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论