Just write SQL. I figured this out when I realized that my application was written in Rust, but really it was a Postgres application. I use PG-specific features extensively. My data, and database, are the core of everything that my application does, or will ever do. Why am I caring about some convenient abstractions to make it easier to work with in Rust, or Python, or whatever?
Nah. Just write the good SQL for your database.
I'm not doubting that it can be done, I'm just curious to see how it's done.
The resulting codebase was about 50kloc of C# and 10kloc of SQL, plus some cshtml and javascript of course. Sounds small, but it did a lot -- it contained a small CMS, a small CRM, a booking management system that paid commissions to travel agents and payments to tour operators in their local currencies, plus all sorts of other business logic that accumulates in 15+ years of operation. But because it was a monolith, it was simple and a pleasure to maintain.
That said, SQL is an objectively terrible language. It just so happens that it's typically the least of all the available evils.
I completely agree, it is absolutely essential to understand what SQL is emitted, and how SQL works. Perhaps the strawman argument against ORMs is that they preclude you from knowing SQL. They don't.
ORMs are way more trouble than they’re worth because it’s almost easier to write the actual SQL and just map the resulting table result.
Also, in many non-tech companies the database admins were historically a consistent IT resource even when no other developers were available, so SQL gets leveraged extensively. When your only tool is a hammer, most of your problems end up being weirdly nail shaped.
ORMs are one of those things that a lot of people think is a replacement for knowing SQL. Or that ORMs are used as a crutch. That has nothing to do with it. Very similar to how people here talked about TypeScript 10 years ago in a very dismissive way. Not really understanding its purpose. Most people haven't used something like Entity Framework either which is game changing level ORM. Massive productivity boost, and LINQ rivals SQL itself in that you can write very small yet powerful queries equivalent to much more complex and powerful SQL.
Since then I've embraced ORMs for CRUD. I still double-check its output, and I'm not afraid to bypass it when needed.
I've definitely had issues when using sqlalchemy where some REST API type returns an ORM object that ends up performing many queries to pull in a bunch of unnecessary data. I think this is harder to do accidentally with SeaORM because the Rust type system makes hiding queries and connections harder.
Most of my usage of SeaORM has been as a type query builder, which is really what I want from an ORM. I don't want to have to deal with lining my "?" or "$1" binds or manually manipulate strings to build a query. IMO a good query builder moves the experience closer to writing actual SQL, without a query builder I find myself writing "scripts" to write SQL.
At my new company, the use of stored procedures unchecked has really hurt part of the companies ability to build new features so I'm surprised to see what seems like sound advice, "don't use stored procedures", called out as a cargo cult.
In contrast, every company I've joined that used Entity Framework had enterprise products that ended up being a tightly coupled mess from IQueryable<T> being passed around like the world's favourite shotgun.
You may not need to use an ORM, but hand writing SQL, especially CRUD, should be a terminable offense. You _cannot_ write it better than a process that generates it.
"Bad programmers worry about the code. Good programmers worry about data structures and their relationships”
Some quotes stick with you throughout your whole career.
My biggest learnings:
Don't prematurely normalize data, but if it is obvious it can always stay normalized, normalize it. Read the normal forms. Learn about indexing and how data is actually being stored on disk. Just knowing about indexes is a huge advantage even today. Understand and know when to use different styles of data storage: row oriented, column oriented, key value, bigtable style (2d key value), document (rare). Pick good systems. Spend more time than you think you should designing your data. The system is often easy if the data is right. Learn ACID and CAP theorem. Learn when and where you can trade on fundamental database principles in your data model for performance or ease of development. Honestly, a lot of this stuff senior engineers at big tech are just expected to know these days, but it still isn't really obvious and not everyone has big tech problems. Still if you know how to solve the problems at scale and you can get out of your own way it is much easier to write smaller systems (most problems people have).
So in terms of resources, go learn about each of those concepts. Read papers. Ask an LLM about them. Play with databases and storage systems. Maybe try to write your own simple database. Go read about how people design massively scaled distributed systems and what systems they use to manage data. Just like with programming languages, be flexible and open minded. Read about how distributed systems work (CAP theorem). Almost all data systems make tradeoffs in that realm to meet cost/performance/implementation goals.
It's definitely worth learning SQL very well, but you also need to learn the data structures your RDBMS uses, how queries translate into operations on that data, and what those operations look like in a query plan.
You can go surprisingly far with just that knowledge.
A great resource is https://use-the-index-luke.com/
The relational model is pretty simple though. Pandas is an awful mess.
Things like allowing repeat clauses, compute select before where, etc are what solve for composition issues
Do they though? I've been writing SQL for over twenty years, and my experience is that LLMs have been better at writing it than I am for at least most of 2025, for most use cases. I have zero doubt that I will only be writing SQL when I want to for fun no later than sometime 2027.
Wow, bad career choices?
By the time you are referring to, we were already on the classical 3 tier architecture, the
There are indeed Web frameworks for RDMS, that allow to expose the database as microservices, like Oracle's APEX, which grew out of Oracle's Visual Basic version, which used PL/SQL instead of BASIC.
The basic thesis is that the relational model and SQL has been the prevailing choice for database management systems for decades and that won't change soon.
Resubmitted because it's a good one: https://news.ycombinator.com/item?id=46359878
I’ve been heads-down on publishing a JavaScript full-stack metaframework before the end of the year. However, in the past two weeks I’ve been goaded by Claude Code to extract and publish a separate database client because my vision includes Django-style admin/forms. The idea is to use Zod to define tables, and then use raw SQL fragments with JavaScript template tags. The library adds a tiny bit of magic for the annoying parts of SQL like normalizing join objects, taking care of SELECT clauses and validating writes.
I’m only using it internally right now, but I think this approach is promising. Zod is fantastic for this use-case, and I’m sad I’ve only just discovered it.
IMO for machine-to-machine talk we should not be using a long text that needs to be parsed carefully and securely on the other side, but rather a structured structure that's easy to de-serialize (like AST packed into a protobuf, but for SQL). So that any invalid SQL parameters like "1;DELETE FROM users;--" would just fail to parse.
It may be called ABI, although it may be textual as well (like json), not necessarily binary (like protobuf).
PostgreSQL already supports binary wire protocol, but I never seen it's being used, instead people prefer sending raw SQL strings designed for humans even from applications.
And subling commenters say that all you need is raw SQL and results mapping to your code. Which I did for a while, but found that mapping is a lot of copy-pasta with minor diffs, a burden to maintain. So it's easier to use a thin library like JOOQ for mapping, or use only the mapper part of a bigger ORM framework like Django/Hibernate.
And my argument is that it's easier to map to/from a concise strongly-typed ABI/API structs instead of one raw SQL string with its structure designed for human reading/writing, like SELECT before FROM. There are such ABI-s, but they are DBMS-specific, while SQL is less so.
Also it makes an extra round-trip to server to prepare the query.
I understand that's the convention according to the IEEE and Wikipedia [1], but the name itself - Structured Query Language - reveals that its purpose is limited by design. It's a computer language [2] for sure, but why programming?
[1] https://en.wikipedia.org/wiki/List_of_programming_languages
https://www.reddit.com/r/SQL/comments/81barp/i_implemented_a...
Btw this runs in sqlite, you can try it yourself if you are interested.
Source: I was thinking of creating a programming language paradigm like sqlite/smalltalk once where resumed execution/criu like possibilities were built in. Let me know if someone knows something like this too. I kinda gave up on the project but I knew that there was this one language which supported this paradigm but it was very complicated to understand and had a lot of other first time paradigm like the code itself / the ast tree is sort of like a database itself but so the tangential goes.
Also, even within the standard itself, it allows for declarative programming.
The advice to learn SQL is because it's everywhere. Now it has inertia, and a better way of doing things has an uphill battle. In 1980-s somebody compared working with SQL to drinking data through a straw, comparing to swimming in data with APL. We had a recent article comparing modern SSD delays and RAM sizes to those which defined architectures of SQL systems of recent decades - we can perhaps reengineer our databases better for modern opportunities. But all these approaches have to deal with SQL as an entrenched technology. Probably a task for a company of a Google class.
That in itself is fine, of course. Less fine is the author's thoughtless assumption that their readers are all learning about it too.
Put it together, it's pure gold!
If I was going to chose a "third" language I'd say regex.
https://en.wikipedia.org/wiki/Transact-SQL
SQL/PSM is a general ISO standard that grew out of Oracle PL/SQL, is rooted in ADA, and is implemented by a large range of databases.
https://en.wikipedia.org/wiki/SQL/PSM
Standards are important.
When it comes to procedural logic in particular… you have almost zero chance you’re dropping into that into another database and it working — even for rudimentary usage.
SQL-land is utterly revolting if you have any belief in standards being important. Voting for Oracle (itself initialized as a shallowly copied dialect of IBM SQL, and deviated arbitrarily) as the thing to call “standard” is just offensive.
I was aware that EnterpriseDB developed "deep Oracle compatibility" and sold the resulting code to IBM for Db2 several years ago.
I think you are [more than] a bit behind the times?
https://www.cnet.com/culture/ibm-puts-oracle-to-the-sword-wi...