定义猪的模型和营养需求模型

This commit is contained in:
2025-11-20 14:38:36 +08:00
parent c697e668e3
commit 6ca101727a
6 changed files with 121 additions and 4 deletions

View File

@@ -250,9 +250,20 @@ func (ps *PostgresStorage) applyCompressionPolicies(ctx context.Context) error {
// creatingIndex 用于创建gorm无法处理的索引, 如gin索引
func (ps *PostgresStorage) creatingIndex(ctx context.Context) error {
storageCtx, logger := logs.Trace(ctx, ps.ctx, "creatingIndex")
storageCtx := logs.AddFuncName(ctx, ps.ctx, "creatingIndex")
// 使用 IF NOT EXISTS 保证幂等性
// 如果索引已存在,此命令不会报错
if err := ps.creatingUniqueIndex(storageCtx); err != nil {
return err
}
if err := ps.createGinIndexes(storageCtx); err != nil {
return err
}
return nil
}
func (ps *PostgresStorage) creatingUniqueIndex(ctx context.Context) error {
storageCtx, logger := logs.Trace(ctx, ps.ctx, "creatingUniqueIndex")
// 为 raw_material_nutrients 表创建部分唯一索引,以兼容软删除
logger.Debug("正在为 raw_material_nutrients 表创建部分唯一索引")
@@ -263,6 +274,47 @@ func (ps *PostgresStorage) creatingIndex(ctx context.Context) error {
}
logger.Debug("成功为 raw_material_nutrients 创建部分唯一索引 (或已存在)")
// 为 pig_breeds 表创建部分唯一索引,以兼容软删除 (name 唯一)
logger.Debug("正在为 pig_breeds 表创建部分唯一索引")
partialIndexSQL = "CREATE UNIQUE INDEX IF NOT EXISTS idx_pig_breeds_unique_name_when_not_deleted ON pig_breeds (name) WHERE deleted_at IS NULL;"
if err := ps.db.WithContext(storageCtx).Exec(partialIndexSQL).Error; err != nil {
logger.Errorw("为 pig_breeds 创建部分唯一索引失败", "error", err)
return fmt.Errorf("为 pig_breeds 创建部分唯一索引失败: %w", err)
}
logger.Debug("成功为 pig_breeds 创建部分唯一索引 (或已存在)")
// 为 pig_age_stages 表创建部分唯一索引,以兼容软删除 (name 唯一)
logger.Debug("正在为 pig_age_stages 表创建部分唯一索引")
partialIndexSQL = "CREATE UNIQUE INDEX IF NOT EXISTS idx_pig_age_stages_unique_name_when_not_deleted ON pig_age_stages (name) WHERE deleted_at IS NULL;"
if err := ps.db.WithContext(storageCtx).Exec(partialIndexSQL).Error; err != nil {
logger.Errorw("为 pig_age_stages 创建部分唯一索引失败", "error", err)
return fmt.Errorf("为 pig_age_stages 创建部分唯一索引失败: %w", err)
}
logger.Debug("成功为 pig_age_stages 创建部分唯一索引 (或已存在)")
// 为 pig_types 表创建部分唯一索引,以兼容软删除 (breed_id, age_stage_id 组合唯一)
logger.Debug("正在为 pig_types 表创建部分唯一索引")
partialIndexSQL = "CREATE UNIQUE INDEX IF NOT EXISTS idx_pig_types_unique_breed_age_stage_when_not_deleted ON pig_types (breed_id, age_stage_id) WHERE deleted_at IS NULL;"
if err := ps.db.WithContext(storageCtx).Exec(partialIndexSQL).Error; err != nil {
logger.Errorw("为 pig_types 创建部分唯一索引失败", "error", err)
return fmt.Errorf("为 pig_types 创建部分唯一索引失败: %w", err)
}
logger.Debug("成功为 pig_types 创建部分唯一索引 (或已存在)")
// 为 pig_nutrient_requirements 表创建部分唯一索引,以兼容软删除 (pig_type_id, nutrient_id 组合唯一)
logger.Debug("正在为 pig_nutrient_requirements 表创建部分唯一索引")
partialIndexSQL = "CREATE UNIQUE INDEX IF NOT EXISTS idx_pig_nutrient_requirements_unique_type_nutrient_when_not_deleted ON pig_nutrient_requirements (pig_type_id, nutrient_id) WHERE deleted_at IS NULL;"
if err := ps.db.WithContext(storageCtx).Exec(partialIndexSQL).Error; err != nil {
logger.Errorw("为 pig_nutrient_requirements 创建部分唯一索引失败", "error", err)
return fmt.Errorf("为 pig_nutrient_requirements 创建部分唯一索引失败: %w", err)
}
logger.Debug("成功为 pig_nutrient_requirements 创建部分唯一索引 (或已存在)")
return nil
}
func (ps *PostgresStorage) createGinIndexes(ctx context.Context) error {
storageCtx, logger := logs.Trace(ctx, ps.ctx, "createGinIndexes")
// 为 sensor_data 表的 data 字段创建 GIN 索引
logger.Debug("正在为 sensor_data 表的 data 字段创建 GIN 索引")
ginSensorDataIndexSQL := "CREATE INDEX IF NOT EXISTS idx_sensor_data_data_gin ON sensor_data USING GIN (data);"
@@ -280,6 +332,5 @@ func (ps *PostgresStorage) creatingIndex(ctx context.Context) error {
return fmt.Errorf("为 tasks 的 parameters 字段创建 GIN 索引失败: %w", err)
}
logger.Debug("成功为 tasks 的 parameters 字段创建 GIN 索引 (或已存在)")
return nil
}