Show HN: Node.js ORM to query SQL database through an array-like API
123 points| tilyupo | 1 year ago |github.com
The package is designed to simplify querying SQL databases through an array-like API. Qustar supports PostgreSQL, SQLite, MySQL, and MariaDB, and offers TypeScript support for a robust development experience.
It's in early stage of development. I would like to hear your thoughts about it.
xonix|1 year ago
- need to learn secondary API which still doesn't cover the whole scope of SQL
- abstraction which is guaranteed to leak, because any time you'll need to optimize - you'll need to start reason in terms of SQL and try to force the ORM produce SQL you need.
- performance
- deceptive simplicity, when it's super-easy to start on simple examples, but it's getting increasingly hard as you go. But at the point you realize it doesn't work (well) - you already produced tons of code which business will disallow you to simply rewrite
(knowledge based on my own hard experiences)
DimmieMan|1 year ago
Super fast and easier to use force multiplier in the beginning, but eventually you break free of the siren song and run into some negative that eats away at your time until you reach that “if you had just sucked it up and written the damn sql you’d be done yesterday” stage.
whizzter|1 year ago
My experience with Linq over the years has been great, only time I've needed to go raw SQL was to supply index hints (you can add that to Linq but we opted not to) and doing special things with merge statements. But EF allows you do submit raw SQL queries where needed.
The important part is, when you have a good system that actually provides benefits(Linq is properly typed) and doesn't get in the way or produce weird SQL then it'll work out.
I've only needed to use around 10 raw SQL queries where Linq failed to hundreds or maybe thousands of Linq queries where it worked perfectly well and this includes some fairly heavy queries.
reacweb|1 year ago
hn_throwaway_99|1 year ago
The way I've always put it is "ORMs make the easy stuff a bit easier, and the harder stuff way harder." Just learn SQL, it's not that hard and it's a much better, transferable skill.
aleclarsoniv|1 year ago
It's not released yet, but give it a look :) (v0.1 is almost done)
[1]: https://github.com/pg-nano/pg-nano
j45|1 year ago
Some ORMs have def have some more experience getting optimized in delaying the need to optimize the query, indirectly, or directly by rewriting it.
ORM with a bit of SQL might still be less work than using a nosql db and trying to make it relational, but not.
cambaceres|1 year ago
samstave|1 year ago
LookerML is their abstracted version - but they always have an expander panel for seeing the sql.
---
What I would like is to use this in reverse - such that I can feed it a JSON output from my GPT bots Tribute - and use this to craft a sql schema dynamically into a more structured way where my table might be a mark-down version of the {Q} query - and it does SQL to create table if not exist, insert [these objects from this json for these things into this DB, now these json objects from this output into this other DB. Now I am pulling data into the DB that I can then RAG off as I fill it with Cauldrons of Knowledge I am scvraping for my rabbit-hole project thingamijiggers.
arnorhs|1 year ago
Context:
We've had a lot of ORM frameworks come and go in node.js - sequelize, typeorm etc, but none of them have really caught on.
Things have been changing a lot lately after typescript took over, so we've seen a bunch of ORMs take off that give you a really good typescript experience.
So, the juggernaut in this space is of course prisma, which is super expressive and over all pretty decent - it comes with its own way to define schemas, migrations etc .. so that might not be everybody's cup of tea. (and then there's the larger runtime, that have lambda-users complaining - though that has mostly been addressed now where the binary is much smaller)
So despite it being a pretty opinionated framework really, what it gives you are really rich typescript integrated queries. And all in all it works pretty well - i've been using it at work for about 3 years and I'm just really pleased with it for the most part.
The newcomer in the space that's gaining a lot of traction is Drizzle - where it's mostly a way to define tables and queries - it also gives you really rich typed queries - and it happens all in TS/JS land.
this project of yours reminds of drizzle - kind of similar in a lot of ways.
I'm super interested to understand how this compares to drizzle and which problems with drizzle this attempts to solve
anonzzzies|1 year ago
efitz|1 year ago
SQL is not a difficult language to learn, and views and stored procedures provide a stable interface that decouples the underlying table schema, allowing for migrations and refactoring of the database structure without having to rewrite a lot of code.
ORMs seem to me to be mostly about syntactic sugar nowadays; I’m worried that the abstractions that they set up insulate the developer from the reality of the system they’re depending on - like any abstraction, they probably work fine right to the very point they don’t work at all.
I’m not complaining about this project; it looks cool and I can see the attraction of staying in a single language paradigm, but I am very wary of abstractions, especially those that hide complex systems behind them.
l5870uoo9y|1 year ago
theonething|1 year ago
except for the the simplest of queries, I always check my ORM based queries by looking at the translated SQL. This seems like common sense to me, but maybe not.
ARandomerDude|1 year ago
Every time you switch languages, or stay in the same language for 2 years, you have to learn another ORM. SQL is about as close as timeless gets in this business.
j45|1 year ago
dangsux|1 year ago
[deleted]
sigseg1v|1 year ago
Looking at the docs, for example the pg connector, I couldn't easily find information about how it parameterizes the queries built through method chaining.
For example, if I run
I am presuming that the unsanitizedInput will be put into a parameter? For me, using ORMs on a team that may include juniors, that is one of the key things an ORM provides: the ability to know for sure that a query is immune to SQL injection.If you had more examples on the connectors of queries like this, and also maybe some larger ones, with the resulting SQL output, I think that might increase adoption.
tilyupo|1 year ago
anonzzzies|1 year ago
Continue doing the excellent work please!
tilyupo|1 year ago
Grazester|1 year ago
EarthLaunch|1 year ago
I'm a game dev and often need to avoid situations where I'm using '.map' to iterate an entire array, for performance reasons. It would feel odd to use the concept, knowing it wasn't really iterating and/or was using an index. Is that how it works?
pjerem|1 year ago
In fact, in EF, an IQueryable (which is the interface you use to query a SQL dataset) implements IEnumerable. So you can 100% manipulate your dataset like a normal array/list.
Sure it comes with its own shenanigans but 90% of the time it’s easy to read and to manipulate.
Eric_WVGG|1 year ago
A bit puzzled by why the connector slots into the query, instead of the query slotting into the connector, given that it’s the connector that’s actually doing the work. I.e. ‘connector.fetch(query)‘ … rather than… ‘query.fetch(connector)‘
tilyupo|1 year ago
But I might be wrong, your idea makes more sense from logical perspective.
v_b|1 year ago
I used to work with TypeORM and really missed using EntityFramework. That actually led me to switch to Mongo (Mongoose).
I'm really looking forward to this project!
tilyupo|1 year ago
wruza|1 year ago
I always wrap .query(…) or simply pass its result to a set of quantifiers: .all(), .one(), .opt(), run(), count(). These assert there’s 0+, 1, 0-1, 0, 0 rows.
This is useful to control singletons (and nonetons), otherwise you end up check-throwing every other sql line. One/opt de-array results automatically from T[] to T and T | undefined. Count returns a number.
Sometimes I add many() which means 1+, but that’s rare in practice, cause sqls that return 1+ are semantically non-singleton related but business logic related, so explicit check is better.
I also thought about .{run,count}([max,[min]]) sometimes to limit destructiveness of unbounded updates and deletes, but never implemented that in real projects.
Maybe there’s a better way but I’m fine with this one.
Edit: messed up paragraphs on my phone, now it’s ok
hu3|1 year ago
richwater|1 year ago
`orderByDesc` seems like it could be better suited for an object constant indicating the sort direction.
``` orderBy(OrderBy.Desc, user => user.age) ```
Overall still very nice and looking forward to seeing more development!
pjerem|1 year ago
tilyupo|1 year ago
codr7|1 year ago
I've had more success modelling database concepts directly in the language; tables, columns, keys, indexes, queries, records etc.
https://github.com/codr7/hostr/tree/main/src/Hostr/DB
tehlike|1 year ago
gedy|1 year ago
tilyupo|1 year ago
mannyv|1 year ago
Which I actually like more, because I want to understand the database, not abstract it away. But dealing with SQL is/can be awkward. This library means I don't have to dynamically build sql queries in code.
Handy!
gsck|1 year ago
Ended up using drizzle and just hated every moment of it. This is definitely going in the "Use this eventually" folder!
ericyd|1 year ago
brap|1 year ago
tilyupo|1 year ago
bearjaws|1 year ago
It seems to be more like knex or https://kysely.dev/
jitl|1 year ago
unknown|1 year ago
[deleted]
spankalee|1 year ago
atishay811|1 year ago
todotask|1 year ago
jdthedisciple|1 year ago
but for nodejs
arrty88|1 year ago
shortrounddev2|1 year ago
EGreg|1 year ago
why is codegen bad?
joseferben|1 year ago
marcelr|1 year ago
nsonha|1 year ago
why is this arbitrary property desirable?
shortrounddev2|1 year ago
layer8|1 year ago
v_b|1 year ago
But the OP isn't wrong; all the methods used to construct the query also function as instance methods of arrays in both JavaScript and TypeScript.
unknown|1 year ago
[deleted]
fourseventy|1 year ago
notsylver|1 year ago
I don't like ORMs for lots of reasons but I find them a necessary evil. How do you deal with that in plain SQL, when a query can look completely different depending on the variables?
tilyupo|1 year ago
I think Qustar is closer to a query builder than ORM tbh. You can compose arbitrary queries using it.
hk__2|1 year ago
When your queries become very complex having a good ORM like SQLAlchemy in Python is a life-saver.
unknown|1 year ago
[deleted]
khy|1 year ago
The DSL is nice for simple querying and for composing queries based upon user input. But, for anything slightly complex, I found it's better to just use regular SQL.
unknown|1 year ago
[deleted]
FutureCrafter|1 year ago
[deleted]
thr0w|1 year ago
[deleted]
unknown|1 year ago
[deleted]
matt-p|1 year ago
[deleted]
unknown|1 year ago
[deleted]
_1|1 year ago
[deleted]
hahn-kev|1 year ago
enobrev|1 year ago
This is mostly for making sure my code is up to date with the database. A migration _requires_ a code-change due to the orm code-gen and thus i can't deploy the migration until I ensure my codebase is ready for it
Overall, I would much prefer native SQL support in whatever language I'm working in. But a light ORM tends not to be a terrible trade-off.
Also I like this style of orm because sometimes the order of definining SQL is annoying to me. I prefer to start with the "from" and the joins, then add the conditions, and finally, the columns, which likely reference the other parts and thus make more sense at the end.
gmac|1 year ago
But this one looks nice too.
randomdata|1 year ago
Why SQL itself isn't designed to composable, and why we are happy with that remaining the status quo, will remain one of life's mysteries.
szundi|1 year ago
AFTER you learned to use it hahahhahahhhhahha - evil laughter.
Ps I love hibernate.
unknown|1 year ago
[deleted]
unknown|1 year ago
[deleted]
wredcoll|1 year ago
[deleted]
unknown|1 year ago
[deleted]