Using Knex without connection, then execute with connection
See original GitHub issueHi guys
Let’s say I have a service called QueryBuilderService where I have the details of each of the queries I use in my app.
Let’s say I have another service, DatabaseService, which uses QueryBuilderService but also takes care of handling transactions and reusing multiple queries (for example, createUser() in DatabaseService calls createUser() and getUser() in QueryBuilderService, within a transaction).
My question is: I am currently using a knex connection inside both services. I create it in DatabaseService and I pass it to QueryBuilderService as a constructor argument. Basically it looks like this:
class DatabaseService() {
constructor() {
...
this.query = new QueryBuilderService(myKnexConnection);
}
getUsers() {
return this.query.getUsers()
.then(/* do something */);
}
}
class QueryBuilderService() {
constructor(knexConnection) {
...
this.knex = knexConnection;
}
getUsers() {
return this.knex.select('users');
//etc etc etc
}
}
I want to get rid of that dependency: I want QueryBuilderService to use knex as a query building library only and no longer receive the connection in the constructor. I know this can be achieved, what I don’t know is how to specify the connection from the “outside” (when calling any QueryBuilderService method from DatabaseService).
Do you guys have any idea?
Thanks in advance!
Issue Analytics
- State:
- Created 6 years ago
- Comments:16 (9 by maintainers)
You can use knex as a plain query builder if you initialize it without connection parameters like this:
Notice that query was just built, but not compiled to sql and bindings nor it is executed.
If you want now execute the query above, there is no official way to do it with knex. However for example in tests there is currently used trick where you would execute that query like this:
Anyways this is not nice at all and may be broken by accident in future knex versions, because this is not documented functionality of knex and will never be in this format.
Other less hacky way to do this would be to always pass connection that is used to run the query to each query method that is how for example objection ORM recommends passing the connection pool / transaction in which knex instance its query should be ran.
EDIT: this last part was pretty much the same that is suggested by @wubzz above 👍
I might be mistaken but I think you’re confusing
myKnexConnection
with an instance ofrequire('knex')({...})
. The knex instance is not a connection in itself, all that stuff is handled “in the background” of knex, so to speak. See pool settings in initialize.Spontaneous response is you won’t be able to completely get rid of having to supply the argument one way or the other, but perhaps an idea is to have static methods in order to lose the need for a constructor. For example:
Hope I didn’t misunderstand.
Edit: To be clear,
queryBuilder
argument to QueryBuilderService could either be a pooled clientdbClient
or a transaction object created throughdbClient.transaction
(for your example of createUser + getUser).