From f24729206b1663ec210f7ab14d54d93d0084da75 Mon Sep 17 00:00:00 2001 From: Lance Add <1196661499@qq.com> Date: Sun, 28 Sep 2025 17:57:27 +0800 Subject: [PATCH] fix(database/gdb): Resolved the schema error in the database output log when using the database sharding feature (#4319) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit error log ``` 2025-06-18T15:36:08.315+08:00 [DEBU] {10a3b0cfd9124a186b89b07f50e67ce6} [ 0 ms] [default] [db_0] [rows:1 ] SELECT `id`,`custom_name` FROM `custom` WHERE `id`=1 LIMIT 1 2025-06-18T15:36:09.259+08:00 [DEBU] {10a3b0cfd9124a186b89b07f50e67ce6} [ 1 ms] [default] [db_0] [rows:1 ] SELECT `id`,`custom_name`,`remark`FROM `custom` WHERE `id`=2 LIMIT 1 ``` right log ``` 2025-06-18T15:36:08.315+08:00 [DEBU] {10a3b0cfd9124a186b89b07f50e67ce6} [ 0 ms] [default] [db_0] [rows:1 ] SELECT `id`,`custom_name` FROM `custom` WHERE `id`=1 LIMIT 1 2025-06-18T15:36:09.259+08:00 [DEBU] {10a3b0cfd9124a186b89b07f50e67ce6} [ 1 ms] [default] [db_1] [rows:1 ] SELECT `id`,`custom_name`,`remark`FROM `custom` WHERE `id`=2 LIMIT 1 ``` ``` type DbShardingRule struct { } func (d *DbShardingRule) SchemaName(ctx context.Context, config gdb.ShardingSchemaConfig, value any) (string, error) { if name, ok := value.(string); ok && (len(name) > 0) && gstr.HasPrefix(name, config.Prefix) { return name, nil } return "default", nil } func (d *DbShardingRule) TableName(ctx context.Context, config gdb.ShardingTableConfig, value any) (string, error) { return "", nil } ``` ``` config := gdb.ShardingConfig{ Schema: gdb.ShardingSchemaConfig{ Enable: true, Prefix: "db_", Rule: &DbShardingRule{}, }, } dao.Custom.Ctx(ctx).Sharding(config).ShardingValue("db_0").Where("id", 1).One() dao.Custom.Ctx(ctx).Sharding(config).ShardingValue("db_1").Where("id", 2).One() ``` 我有两个完全一样的数据库db_0和db_1,两个custom表里都只有一条数据,id是1和2,执行上面两条查询得的结果是正确的, 输出日志中应该分别是`[default] [db_0]`和`[default] [db_1]`,但是实际输出的都是`[default] [db_0]`, 查看具体代码实现,该日志由Core实例中获取group和schema构成,而实际执行sql时如果使用了分库特性那么执行sql的link会使用当前面schema重新生成,但是没有重新赋给Core实例,所以输出日志的时候还是错的,只需要在生成link后生成日志前把schema赋给Core就行,方法执行完成后defer将schema重置回去,防止有人重复使用同一个gdb对象造成困扰 ![SCR-20250618-ovoc](https://github.com/user-attachments/assets/815c364e-939f-4a2c-9669-d5b7d2742511) ![SCR-20250618-ovvk](https://github.com/user-attachments/assets/e7d0e375-78e6-4748-90ac-d02dba18720f) ![SCR-20250618-ozsu](https://github.com/user-attachments/assets/faa6d69b-331e-476b-8bf8-f62e564b04d3) ![SCR-20250618-ozwj](https://github.com/user-attachments/assets/15c524dc-dc19-4499-a3d3-32bf1d918a3a) --- database/gdb/gdb_model_hook.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/database/gdb/gdb_model_hook.go b/database/gdb/gdb_model_hook.go index 509878841..8b23337b4 100644 --- a/database/gdb/gdb_model_hook.go +++ b/database/gdb/gdb_model_hook.go @@ -159,6 +159,10 @@ func (h *HookSelectInput) Next(ctx context.Context) (result Result, err error) { if err != nil { return } + h.Model.db.GetCore().schema = h.Schema + defer func() { + h.Model.db.GetCore().schema = h.originalSchemaName.String() + }() } return h.Model.db.DoSelect(ctx, h.link, toBeCommittedSql, h.Args...) } @@ -195,6 +199,10 @@ func (h *HookInsertInput) Next(ctx context.Context) (result sql.Result, err erro if err != nil { return } + h.Model.db.GetCore().schema = h.Schema + defer func() { + h.Model.db.GetCore().schema = h.originalSchemaName.String() + }() } return h.Model.db.DoInsert(ctx, h.link, h.Table, h.Data, h.Option) } @@ -238,6 +246,10 @@ func (h *HookUpdateInput) Next(ctx context.Context) (result sql.Result, err erro if err != nil { return } + h.Model.db.GetCore().schema = h.Schema + defer func() { + h.Model.db.GetCore().schema = h.originalSchemaName.String() + }() } return h.Model.db.DoUpdate(ctx, h.link, h.Table, h.Data, h.Condition, h.Args...) } @@ -281,6 +293,10 @@ func (h *HookDeleteInput) Next(ctx context.Context) (result sql.Result, err erro if err != nil { return } + h.Model.db.GetCore().schema = h.Schema + defer func() { + h.Model.db.GetCore().schema = h.originalSchemaName.String() + }() } return h.Model.db.DoDelete(ctx, h.link, h.Table, h.Condition, h.Args...) }