gormのPluckの「0 rows affected or returned」
開発業務でgorm(v1)を使用しています。
以下のように、ログ出力をONにしてPluckで検索するtest.goを実行すると、fruitsテーブルに格納されている結果が取得できているにも関わらず、0 rows affected or returned
と表示されます。
// ...
f := fruit{}
db = db.Model(&f).Pluck("name", &name)
fmt.Println(name)
// ...
[2020-08-20 01:20:03] [3.66ms] SELECT name FROM `fruits`
[0 rows affected or returned ]
[みかん りんご なし もも さくらんぼ]
gormのログを出力を確認しながら実装などしてるので、ログを見て一瞬「データが取れてないのか!?」とギョッとすることがあります。
こうなっているのには何か意味があるのだろうか…と思ったのでgormの中身を見てみました。
検索結果の行数がちゃんと表示されるFind()
などでは、内部でcallCallbacksを呼び出し、
// Find find records that match given conditions
func (s *DB) Find(out interface{}, where ...interface{}) *DB {
return s.NewScope(out).inlineCondition(where...).callCallbacks(s.parent.callbacks.queries).db
}
最終的にcallback_query.goの中で取得した行数を数えているようです。
...
for rows.Next() {
scope.db.RowsAffected++
...
Pluckの場合はメソッドの中で、scope.goのpluck
を呼び出しています。
func (s *DB) Pluck(column string, value interface{}) *DB {
return s.NewScope(s.Value).pluck(column, value).db
}
scope.goのpluck
の中身を見てみると、Find
とは違い、取得した行数を数えていないようです。
...
rows, err := scope.rows()
if scope.Err(err) == nil {
defer rows.Close()
for rows.Next() {
elem := reflect.New(dest.Type().Elem()).Interface()
scope.Err(rows.Scan(elem))
dest.Set(reflect.Append(dest, reflect.ValueOf(elem).Elem()))
}
if err := rows.Err(); err != nil {
scope.Err(err)
}
}
...
ではここで行数を数えるようにすれば検索できた行数をログに出せるようになるのか…と考えたところでv2の方のプルリクに修正が上がっているのに気づきました。
rows affected or returned is zero when use Pluck()/Count()/Preload(many2many)
scope.goのpluck
に行数を数える処理が追加されてました。
ただのバグで、Count
とPreload
も同様に行数が数えられてなかったみたいです。
gormはちょこちょこバグっぽい挙動があるので、不思議に思ったらときどき中身を見ながらうまく付き合っていきたいですね。。
Author And Source
この問題について(gormのPluckの「0 rows affected or returned」), 我々は、より多くの情報をここで見つけました https://qiita.com/ta_nuki/items/56c035a05215689acfc9著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .