Closed QAnders closed 3 years ago
I'll defer to @jeremydaly here, but my gut says we should keep the Data API Client as unopinionated as possible, so people can bring their own supplementary tools (like knex, or an ORM). There's certainly nothing wrong with using knex in conjunction with data-api-client.
So, no, there's no "supplementary tools" it's more like a "helper" function so that I don't have to type in the WHERE
condition twice.
What I need to do by using parameters (the original code) is something like:
let result = await query(
'SELECT * FROM table where id=:id and category=:category and whatevs=:whatevs',
{ id: 3, category: 'Category 2', whatevs: 'here' }
);
With my addition you don't have to add the parameters as the "object" adds them so with my "helper" the same code would be:
let result = await queryFromObject(
'SELECT * FROM table',
{ id: 3, category: 'Category 2', whatevs: 'here' }
);
The result is the exact same between these two, just that I don't have to type the where id=:id and category=:category and whatevs=:whatevs
as it is generated from the object itself.
I wasn't referring to your code as a supplementary tool. My point was that it might be better to keep data-api-client unopinionated, so people can decide what tools (like knex) to supplement as far as query-building goes.
BTW, you're missing some use cases, e.g. WHERE x IN y
, WHERE x IS NOT NULL
, WHERE x >= y
, etc.. not to mention even more complex cases such as subqueries.
Is there any reason you're ditching knex? As I mentioned, there's nothing wrong with using knex's query-builder in conjunction with data-api-client. I'm doing so myself, and it's a huge time-saver.
But this is Jeremy's thing so I'll let him weigh in. 🙂
Sorry if I am thick but IMO my addition is "unopinionated" as it has no reference or connection to any other "tools". It's just a "lazy-mans" try to avoid writing the same code twice... :)
I am aware of the missing use-cases, it's just to serve as a simple solution for now. INSERT
is not working either of course...
Ideally I'd like to add something more similar to what knex
has (again not as opinionated) but to borrow their idea of having, e.g. .select()
, .update()
, insert()
and .delete()
as functions and the same as knex
, e.g.:
const result = await dbApiClient('table').select('*', {id: 3}); // ==> 'SELECT * FROM table WHERE id = 3'
const result = await dbApiClient('table').update({name: 'Anders'}, {id: 3}); // ==> 'UPDATE table SET name='Anders' WHERE id = 3'
I guess I don't see the point in reinventing the wheel, when knex already exists and is a very extensive query-builder.
Hmm... I'd just like to make it "convenient"... my use-case is that I'd like to be able to run the Data API only in a AWS Lambda and be able to use it in the "simplest" way possible (and that to me is with as few lines of code as possible). That I accomplish by using the "data object" to also set the column names, the same way knex
is doing it.
Sure, knex
is awesome at generating SQL but adding knex
to my project is yet another module that needs to be loaded and risk messing things up, further knex
requires a connection object to work so I have to instantiate knex
with the DB connection as well, "stealing" DB connections unnecessarily and I would also have to add the DB params (and password) for the knex
config. As the Data API SDK supports using Secrets out-of-the-box there is no need for me to add the DB credentials at all in a "pure" Data API solution...
You don't need to instantiate a connection in knex. In my code, I'm simply doing this:
import Knex from 'knex';
const knex = Knex({ client: 'pg' });
And then I can freely build queries with it.
Sorry, and for your question if we are ditching knex, no, we are not but we have a few "high load" Lambdas running large batch jobs that is messing with our Aurora Serverless (PG) and it is dying because it runs out of connections and can't scale up in time because of a large number of INSERT and UPDATE's...
AWS Support guided me to this repo and told me to try and run the "batch loads" using the Data API only and not a native DB connection (=knex
)
You don't need to instantiate a connection in knex. In my code, I'm simply doing this:
import Knex from 'knex'; const knex = Knex({ client: 'pg' });
And then I can freely build queries with it.
Ah, thanks, didn't know that! Then it makes more sense... still a bit of code overload though... ;)
What if you shoved all these jobs into SQS, and had Lambda pull from that queue and then insert records from there? Sounds like an architectural issue that I'm thinking could be solved in a creative way using AWS's other services.
But I'm just spitballing randomly here, as I don't know exactly what you're trying to do.
What if you shoved all these jobs into SQS, and had Lambda pull from that queue and then insert records from there? Sounds like an architectural issue that I'm thinking could be solved in a creative way using AWS's other services.
But I'm just spitballing randomly here, as I don't know exactly what you're trying to do.
Thanks, problem is that even with SQS "offloading" all objects has to be created in sequence as they are related in DB and I need to keep each object (Invoices, Orders, Order responses, etc.) in their own transactions so it's a bit of a challenge... :)
For now, I have created my suggested PR as a function in my own code to use that in turn calls the data-api-client
after parsing the SQL.
If you don't like the idea I might create a "wrapper" that'll use the data-api-client
and if it is any good I might put it onto npm publicly if anyone else see the benefit of it... :)
Thanks for your time!
So, thanks a million for this, very useful!
We are currently migrating a lot of queries from
knex
to use Aurora Data API and asknex
is always using objects as "conditions" I put together a little "helper" to be able to create the "where" condition from objects.The idea is that you create an object which matches the DB table column names and add the values you need for the condition(s).
I am no Node.js talent but seems to do the trick... :)
I couldn't push any new branch so here's the solution I made in snippets!
Code added:
Tests added under
Querying
: