Live data from Hacker News

SQLx – Rust SQL Toolkit

github.com

81–90 of 101 posts

Re: SQLx – Rust SQL Toolkit

#81
post #62

Earlier quoted context omitted.

Is something like SeaQuery[0] what you're talking about? [0] https://github.com/SeaQL/sea-query/

SeaQuery looks like a similar dynamic query builder for Rust as Kysely is for JS/TS, so yeah, that'd probably solve the dynamic query problem. But I think parent wasn't so much asking for another library but for patterns. How do people who choose to use a no-dsl SQL library, like SQLx, handle dynamic queries? Especially with compile-time checking. The readme has this example: ... WHERE organization = ? But what if yo…

I generally avoid DSLs as they don't bring much... except for this exact use-case. Dynamic queries is pretty much what a query builder is for: you can avoid a dependency by rolling your own, but well it's not trivial and people out there have built some decent ones.

So, if I have this use-case I'd reach for a query builder library. To answer the question of "how to do dynamic queries without a query builder library", I don't think there's any other answer than "make your own query builder"

Re: SQLx – Rust SQL Toolkit

#82
post #62

Earlier quoted context omitted.

SeaQuery looks like a similar dynamic query builder for Rust as Kysely is for JS/TS, so yeah, that'd probably solve the dynamic query problem. But I think parent wasn't so much asking for another library but for patterns. How do people who choose to use a no-dsl SQL library, like SQLx, handle dynamic queries? Especially with compile-time checking. The readme has this example: ... WHERE organization = ? But what if yo…

I agree with you that dynamic query building can be tedious with a pure SQL approach. The use case you are describing can be solved with something alone the lines of: WHERE organization = $1 AND ($2 IS NULL OR starts_with(first_name, $2) AND ($3 IS NULL OR birth_date > $3) With SQLx you would have all the params to be Options and fill them according the parameters that were sent to your API. Does that make sense?

That's relying a lot on the DB engine, which will struggle as the condition gets more complex. I've had MySQL make stupid choices of query plans for very similar queries, I had to break the OR into UNIONs

Re: SQLx – Rust SQL Toolkit

#83
I am not much into Rust ATM. I am quite comfortable with C++. So here it goes my question:

I use sqlpp11 in C++.

I generate code and I can use it with strong typing by including some headers. This Rust crate seems to provide compile-time checking.

But it will give me code-completion? It is very nice that by pressing '.' you know what you potentially have.

Re: SQLx – Rust SQL Toolkit

#84
post #46

I used SQLx with an SQLite database and ran into connection pool problems that would cause the database to be unexpectedly dropped. The issues I saw seem to be related to these issues: https://github.com/launchbadge/sqlx/issues/3080 https://github.com/launchbadge/sqlx/issues/2510 The problems did not manifest until the application was under load with multiple concurrent sessions. Troubleshooting the issue by changing…

SQLx is great, but I had a long laundry list of issues with its SQLite support so I forked it into a focused SQLite-specific library. It has now diverged very far from SQLx, and the number of small inaccuracies and issues we fixed in the low-level SQLite bindings is well into the dozens. The library is unannounced, but is already being used in some high-throughput scenarios. https://github.com/cortesi/musq

Musq looks very friendly. I will try it in a future project.

Thank you for sharing it!

Re: SQLx – Rust SQL Toolkit

#85
I first went to sqlx thinking it would be like JOOQ for Rust, but that wasn't the case. It's a pretty low-level library and didn't really abstract away the underlying DBs much, not to mention issues with type conversions. We've since just used rust-postgres.

Re: SQLx – Rust SQL Toolkit

#86
post #44

Earlier quoted context omitted.

It's quite simple really. I want to write a query and have a concrete object as it's return type. The framework that gets me there in the least amount of steps is going to be more intuitive. Let's compare: SQLC - configuration file (yaml/json) - schema files - query files - understand the meta language in query file comments to generate code you want SQLx - env: DATABASE_URL Now does that mean that SQLx is the best p…

Maybe I'm drinking the sqlc Kool aid, but because I'm already using migration files, setting up the config to point to them and a folder of SQL queries was pretty painless. And of course now that I have it, the incremental cost of adding a new query is really low as well

That's all understandable. But like I said I did spend 2 weeks working with SQLc, however when I compared it to just writing the query in my code, the developer experience was miles apart.

You could compare it to people writing CSS, JavaScript and Markup in separate files Vs having just one file in React/Svelte etc. which gives the user the option to combine everything into one.

There maybe a lot of drawbacks from the latter approach but it's makes everything a hell easier for people to just get started building.

Re: SQLx – Rust SQL Toolkit

#87

One thing I don't usually see addressed with the pure-sql approaches is how to handle dynamic query building. The most common example being large configurable forms that display a data grid. Kysely[1] does a good job of starting from this angle, but allowing something like specifying the concrete deserialization type similar to the libraries here. I'm a big fan of sql in general (even if the syntax can be verbose, th…

I find that interpolating strings works pretty well for this use case (which actually switchd TO string interpolation from ORMs at a previous job of mine).

But this is conditional on either your database or your minimal abstraction layer having support for bindings arrays of data with a single placeholder (which is generally true for Postgres).

Re: SQLx – Rust SQL Toolkit

#88
post #2

I have used this as well as many of the other lower-level db drivers (which don't check your SQL at compile time) and I can say I much prefer the latter. My issues with SQLx when I first tried it were that it was really awkward (nigh impossible) to abstract away the underlying DB backend, I expect those issues are fixed now but for some simple apps it's nice to be able to start with SQLite and then switch out with po…

Why would you want to abstract away the underlying database? Wouldn't it better to already use the target DB to cattch potential issues earlier? Also to avoid creating another layer of indirection, potentially complecting the codebase and reducing performance?

> Wouldn't it better to already use the target DB to cattch potential issues earlier?

The target DB can change as a project goes from something mildly fun to tinker with to something you think might actually be useful.

Also I personally find that SQLite is just nice to work with. No containers or extra programs, it just does what you ask it to, when you ask it to

Re: SQLx – Rust SQL Toolkit

#89
post #12

I've been using sqlx with postgres for several months now on a production server with decent query volume all day long. It has been rock solid. I find writing sql in rust with sqlx to be far fewer lines of code than the same in Go. This server was ported from Go and the end result was ~40% fewer lines of code, less memory usage and stable cpu/memory usage over time.

Speaking of Go, if you want compile-time type checking like what SQLx offers, the Go ecosystem has an option that is arguably even better at it: https://sqlc.dev/ It has the advantage that it implements the parsing and type checking logic in pure Go, allowing it to import your migrations and infer the schema for type checking. With SQLx you need to have your database engine running at compile time during the proc mac…

> with SQLx you need to have your database engine running at compile time during the proc macro execution with the schema already available.

FWIW, the compile-time query checking is entirely optional. If you don't use the query syntax checking then you don't need live database and you don't need `sqlx prepare`.

Re: SQLx – Rust SQL Toolkit

#90
post #61

Earlier quoted context omitted.

This is not quite the same thing, because it requires `sqlx prepare` to be run first; and that talks to the database to get type information. In SQLC, on the other hand, query parsing and type inference is implemented from first principles, in pure Go.

sqlc's approach has its limitations. Its SQLite query parser is generated from an ANTLR grammar, and I've encountered situations where valid SQLite syntax was rejected by sqlc due to their parser failing. Type inference was okay, since SQLite barely has any types. The bigger issue I had was dealing with migration files. The nice part about SQLx is that `cargo sqlx database setup` will run all necessary migrations, an…

I believe sqlc can also connect to the database for type inference now too, fwiw.
Post reply on HN