You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 10:57:27