Your Question
I just want query a row by id.
type AccountLocal struct {
ID string `gorm:"primarykey;size:16"` // username
Name string `gorm:"size:24"`
CreatedAt time.Time
UpdatedAt time.Time `gorm:"autoUpdateTime:milli"`
DeletedAt gorm.DeletedAt `gorm:"index"`
}
_db := db.Session(&gorm.Session{PrepareStmt: true})
obj := AccountLocal{}
err := _db.First(&obj, "id = ?", "1").Error
Here is what it generated.
SELECT * FROM `account_local` WHERE `account_local`.`id` = '1' AND `account_local`.`deleted_at` IS NULL ORDER BY `account_local`.`id` LIMIT 1
The document you expected this should be explained
https://gorm.io/docs/query.html#Retrieving-objects-with-primary-key
Expected answer
SELECT * FROM `account_local` WHERE `id` = '1'
BTW:
I think some API design described in this document is a bit inappropriate. Each CRUD API overlaps with each other, for example, many APIs such as 'Find', 'First', etc. all include Where, Sort, and Object Mapping semantics.
Your implementation is very cool, but the API for user is still lacking some clear semantics, such as Select/Find, Where, Sort, Limit, and Object-Mapping (What is the last step of getting the results into go structs). As for 'First' and 'Last', they belong to high-level abstraction, at most as an object mapping, and should not have other semantics like Sort.
In addition, all of the API returned 'DB' object. That method-chaining is pretty cool, but it lacks a clearly end, such as the following example:
db.Find().Sort().Limit().One(&obj) // End of One
db.Find().Sort().First(&obj) // End of First
When executing the object mapping method, it means that it needs to be executed to obtain results. Just return something such as 'gorm.Result' clearly indicates the end.
in chinese
我觉得这个文档里描述的 CRUD API 设计有点不妥,每个方法都做了彼此有交叉的事,比如 Find, First 等等不少 API 同时包含 Where, Sort, 以及对象映射(mapping) 等功能。
你的实现做了非常牛X 的封装,但对外 API 缺少明确的语义,类似 Select/Find, Where, Sort, Limit, 以及对象映射(将结果包装到 go struct 的过程),至于 First 和 Last 顶多作为对象映射接口,不该有排序语义。
此外,所有接口全返回了 DB 对象。链式调用挺好的,但需要有个明确的结束,比如以下例子
db.Find().Sort().Limit().One(&obj) // 结束于 One
db.Find().Sort().First(&obj) // 结束于 First
当执行到对象映射 方法后,就意味着它需要执行得出结果了,返回 gorm.Result 这样的结果更合适。
Comment From: a631807682
Welcome to submit PRs to help us improve the documentation.
Regarding the problem that the finisher API does not end the chain call, this is a good suggestion. There are some historical reasons here, because v1 supports the reuse of db instances. In the update of v2, it is actually not allowed, but this is a breaking change, it may be supported in a subsequent release, probably v3.
Comment From: cupen
@a631807682 …… OK, Maybe I can offer a contribute when I have some spare time. But before that, could you help me how to query a row by id? Just:
SELECT * FROM `account_local` WHERE `account_local`.`id` = '1' LIMIT 1
Not:
SELECT * FROM `account_local` WHERE `account_local`.`id` = '1' AND `account_local`.`deleted_at` IS NULL ORDER BY `account_local`.`id` LIMIT 1
Comment From: a631807682
Do not use gorm.DeletedAt, it is used to mark the deleted state. Use Take instead of First, because First implies sorting
type AccountLocal struct {
ID string `gorm:"primarykey;size:16"` // username
Name string `gorm:"size:24"`
CreatedAt time.Time
UpdatedAt time.Time `gorm:"autoUpdateTime:milli"`
- DeletedAt gorm.DeletedAt `gorm:"index"`
}
_db := db.Session(&gorm.Session{PrepareStmt: true})
obj := AccountLocal{}
- err := _db.First(&obj, "id = ?", "1").Error
+ err := _db.Take(&obj, "id = ?", "1").Error
Comment From: cupen
@a631807682 Oh, that works. Thank you. Cheers!
Comment From: cupen
Maybe this issue should keep open? I will find time to do something.
Comment From: saeidee
Maybe this issue should keep open? I will find time to do something.
Closing the issue with a PR opened to update the docs https://github.com/go-gorm/gorm.io/pull/683