uptrace / bun

SQL-first Golang ORM
https://bun.uptrace.dev
BSD 2-Clause "Simplified" License
3.59k stars 218 forks source link

ScanRows in *bun.Tx #586

Open sdzyba opened 2 years ago

sdzyba commented 2 years ago

Hello @vmihailenco

From docs I understand that it's possible to execute a custom query and scan the results into a custom model. But that's only possible to do on *bun.DB, but not on *bun.Tx because although Tx has Query() method, it doesn't have ScanRows().

Is there a specific reason for that? Or it's actually possible to extend *bun.Tx with ScanRows() method and also add this method to bun.IDB?

vmihailenco commented 2 years ago

It is possible, but ScanRows does not need access to the *bun.Tx - rows already read all data from the tx.

You can do something like this:

rows, err := tx.Query(...)
if err != nil {
    panic(err)
}

err = db.ScanRows(ctx, rows, dest)

We can add tx.DB() and conn.DB() if that helps.

sdzyba commented 2 years ago

Thanks for the answer.

The issue is that we try to abstract away both *bun.Tx and *bun.DB usage under bun.IDB interface because we want to operate with the interface on the application level.

We're switching from go-pg to Bun right now and it is possible to execute .Query() both on go-pg's pg.DBI and bun's bun.IDB, but the difference is that the former accepts model in it's arguments, while the latter expects you to "parse" the rows through ScanRows which is not a part of the interface.

So the only solution for our approach is to have this interface extended. Yes, we could define our own extended interface with ScanRows() added, but generally I'd expect that both Bun and go-pg are having similar interfaces (in terms of functionality, not semantics) out of the box.

jeffreydwalter commented 1 year ago

I have the same issue. There are many areas where the API differences between go-pg and bun make it impossible to do things that were possible in go-pg. Apply() is another place: https://github.com/uptrace/bun/issues/888