Gorm带条件Preload查询所有Stock时Weekly数据为空问题求助
Gorm预加载Weekly数据异常问题解决
数据模型
type Stock struct { ID uint `gorm:"primaryKey"` CreatedAt time.Time `gorm:"default:current_timestamp" json:"created_at"` UpdatedAt time.Time `gorm:"default:current_timestamp" json:"updated_at"` Name string Symbol string CustomSymbol string ScriptType string Industry string ISIN string `gorm:"unique"` Fno bool Daily []Daily Weekly []Weekly Ohlc []Ohlc } type Daily struct { ID uint `gorm:"autoIncrement" json:"id"` CreatedAt time.Time `gorm:"default:current_timestamp" json:"created_at"` UpdatedAt time.Time `gorm:"default:current_timestamp" json:"updated_at"` StockId uint `gorm:"not null;primaryKey" json:"stock_id"` Open decimal.Decimal High decimal.Decimal Low decimal.Decimal Close decimal.Decimal AdjClose decimal.Decimal Volume int Timestamp int `gorm:"not null;primaryKey" json:"timestamp"` Rs decimal.Decimal `gorm:"not null;default:0" json:"rs"` BarComplete bool `gorm:"not null;default:true" json:"bar_complete"` } type Weekly struct { ID uint `gorm:"autoIncrement" json:"id"` CreatedAt time.Time `gorm:"default:current_timestamp" json:"created_at"` UpdatedAt time.Time `gorm:"default:current_timestamp" json:"updated_at"` StockId uint `gorm:"not null;primaryKey" json:"stock_id"` Open decimal.Decimal High decimal.Decimal Low decimal.Decimal Close decimal.Decimal AdjClose decimal.Decimal Volume int Timestamp int `gorm:"not null;primaryKey" json:"timestamp"` Rs decimal.Decimal `gorm:"not null;default:0" json:"rs"` BarComplete bool `gorm:"not null;default:true" json:"bar_complete"` }
问题场景
- 单个Stock查询时,预加载Weekly数据正常:
db.Preload("Weekly", func(db *gorm.DB) *gorm.DB { return db.Order("timestamp desc").Limit(ohlcCount) }).Where("id = ?", stockId).Find(&stocks)
- 查询所有Stock时,带Limit的预加载返回空Weekly数组,去掉Preload内的Order/Limit则正常:
initializers.DB.Preload("Weekly", func(db *gorm.DB) *gorm.DB { return db.Order("timestamp desc").Limit(ohlcCount) }).Find(&stocks)
问题原因
批量查询所有Stock时,Gorm默认的预加载逻辑中,Limit(ohlcCount)会作用于整个Weekly表的全局查询,而非每个Stock的关联数据。这会导致仅取出全局前ohlcCount条Weekly记录,若这些记录无法匹配到所有Stock,就会出现部分或全部Stock的Weekly数组为空的情况。而单个Stock查询时,Limit是针对该Stock的关联数据,因此正常。
解决方案
修改预加载的子查询,明确关联主表的id字段,确保Limit作用于每个Stock的关联数据:
initializers.DB.Preload("Weekly", func(db *gorm.DB) *gorm.DB { // 通过gorm.Expr关联主表的id,限定每个Stock只加载自己的前N条Weekly数据 return db.Where("stock_id = ?", gorm.Expr("stocks.id")).Order("timestamp desc").Limit(ohlcCount) }).Find(&stocks)
内容的提问来源于stack exchange,提问作者Himanshu Pandey
相关产品推荐
相关产品推荐

