Hacker News new | comments | show | ask | jobs | submit login
I don't want to learn your query language (erikbern.com)
289 points by nreece 3 months ago | hide | past | web | favorite | 153 comments



Yeah I think the only way you can use plain, vanilla SQL to query a system is IF its a relational database. Most of the examples are not.. they solve different problems and have vastly different architectures under the hood.

Lucene for example doesn't use SQL because its really solving a different problem - text search. Its a language dedicated to what could only be expressed using something like `LIKE` and regexes in SQL.

Same with Splunk, it addresses a different domain and solves different problems that cant be easily expressed in SQL.

Same with MongoDB.. its not a relational db. Just because there is a mapping from some SQL queries to some Mongo queries, does not mean they are identical databases.

The query language directly impacts the AST generated, which is necessarily tied very closely to the exact capabilities/internals of a system. This post just feels like its based on a cursory glance of what the systems do.

If all Lucene had was regexes, it would not perform much better than a SQL database throwing regexes at strings. Its precisely because the query language is finer-grained that it can be better optimized for that usecase.


> Lucene for example doesn't use SQL because its really solving a different problem - text search. Its a language dedicated to what could only be expressed using something like `LIKE` and regexes in SQL.

There are much better options than LIKE and regexes in SQL for text search. To mention but two:

    SELECT 'a fat cat sat on a mat and ate a fat rat'::tsvector @@ 'cat & rat'::tsquery;
https://www.postgresql.org/docs/current/static/textsearch-in...

    SELECT * FROM articles
    WHERE MATCH (title,body)
    AGAINST ('database' IN NATURAL LANGUAGE MODE);
https://dev.mysql.com/doc/refman/8.0/en/fulltext-natural-lan...

All main engines support full text search in one way or another. TSQL, Oracle, DB2... even SQLite.

What more, these engines all support inverted tree indexes in one form or another - i.e. the same type of index Lucene uses - to make this efficient. This is completely different from the typical LIKE or regex query against a column with a BTree index.


If you truly believe that MySQLs MATCH comes close to be plethora of different queries you can fire at an ES or Solr server, you’re missing some fundamental part of the picture. Sure, it might have been possible to squeeze Lucenes or elasticsearchs query language into something that looks like SQL, but it would still remain a custom SQL dialect which would require substantial domain knowledge to handle. The fundamental problem in that domain is not the query language, it’s knowing which query on which underlying field definition will produce the desired result. Squeezing the query language into some sql-like shape will provide marginal gain at best.


I can't speak for MySQL, as I haven't used it in a while, but I'd pick a properly configured Postgres full text over ES in a heart beat, if only because it means one less dependency (tree) to worry about. (As a bonus, the beauty of Postgres allows to use ES as an index type if you so wish [0].)

Also:

> Squeezing the query language into some sql-like shape will provide marginal gain at best.

... is disingenuous at best. In both examples I raised (and in the ones you'll find if you query the others) the engines have functionality to accept user input pretty much as is - meaning as your typical mom would type it in a search field.

If you need extra criteria from there and the dialect's full text syntactic features, you can use regular SQL conditions (and joins, and aggregates, etc.) on the subset of records found. The most discriminating criteria/index will be the one related to the search query in most cases. And when not, lucky you - your query planner did not hammer everything with the same sledgehammer, thus demonstrating why you should be using SQL.

[0]: https://github.com/zombodb/zombodb


I'm not sure what "properly configured" means but ES has huge array of options for search which something simple like MATCH (title,body) AGAINST ('database' IN NATURAL LANGUAGE MODE) can't even begin to coming close to cover. Look at their docs, there are literally hundreds of options, dozens of search modes, dozens of analyzers and filters, scoring configurations, and so on and so forth. I am not familiar specifically with Postgres but I highly doubt Postgres supports all that or even a serious part of that - at least natively.

What I see at your zombodb link is just a way to make Postgres proxy requests to ES - complete with ES syntax and/or Query DSL. The only difference is that instead of connecting to ES directly you connect to Postgres and then add "SELECT" thing in front of your ES Query DSL. If it makes something easier, fine, but it's not "Postgres full text over ES".


What you really mean is that all of the major DB engines created their own query language for dealing with full-text search. None of those things are SQL, they are extensions to SQL.


If memory serves me well, ANSI SQL (the W3C of SQL) recommends the syntax adopted by TSQL and DB2. So technically, some flavors of this are not extensions to SQL, but indeed part of it.

Think of it as browser prefixes. Sooner or later all engines agree on a common syntax, with each one needing to support some legacy code.

And in contrast with what happens when you use some third party app, you can further filter matched rows, join them with other tables to your heart's contents, aggregate them, apply window functions, and what have you.


While everything, including the Wikipedia definition of SQL defines it as tied to relational databases, one of our industry's biggest flaws is not realizing that the basic concept of a Structured Query Language is that it can handle nearly all types of structures, including non-relational ones.

Take a look at the most recent versions of the SQL standard, say SQL:2016, and you see it handles document type data (JSON) pretty well too. The syntax isn't what we're used to, but it works pretty well.

I know that SQL can do more when you separate its conceptual foundation from relational databases. It's an expression language, an interface language to structured data.

I used to work on a platform that could translate SQL into NoSQL databases and SQL databases alike, it involves translating the expression into something that fits the native data model. For something similar look at Apache Drill, Dremio, Hive or PrestoDb and how they hide different types of databases behind interfaces that make them compatible with SQL.

I can admit, shoehorning SQL as it is onto a non-relational source (ex. Graph databases or search) isn't totally clean. But I believe it can evolve further as a standard to address that.

It requires more work in middleware to interface between SQL expressions and heterogeneous technology. And getting creative with the language constructs themselves. The power of data projection, data shaping and filtering alone, not to mention aggregation, etc. is undeniable in my opinion.

Disclaimer: I used to work for a company that built data federation software which supported SQL in front of heterogeneous sources. So what I am saying I know to be factual in most cases (although difficult!).


Too bad normal people can't read the SQL standard without spending a huge amount of money. I just looked it up, and it looks like picking up all the ISO/IEC 9075 2016 specs would end up costing CHF1762 ($1819.09 in USD).

Developers are also unable to become involved or voice their concerns in any meaningful way without spending an even larger amount of money to participate in their committees. Oh, and AFAIK all development happens behind closed doors, so good luck figuring out why certain design decisions were made.


This is true.


But why? Yes, you can make all languages start queries with SELECT. In fact, for graph DBs you have SPARQL (which looks exactly like SQL if you squint a bit), and Elastic has its own SQL interface. But what happened to best tool for the job? Why try to shoehorn a relational database language into dealing with data that are not relational tables in their nature, instead of using approaches that work better?

I mean, I understand there's a use case where it can be useful, such as SQL query builders or APIs that support only SQL, but in general case when you don't need one interface to rule them all, what's the use of shoehorning everything into SQL?


Yeah the post seems to confound two mostly unrelated issues. I agree with not reinventing the wheel for relational databases, SQL is fine.

But for other domains, the query languages arose out of need, not because someone felt like it. SQL is hot garbage for for non-trivial logic. I can't even imagine what splunk would look like if you had to query it with SQL.

If anything, SPL (or rather the piped operators approach) would make a lot more sense as the groundwork for a universal query language that works across many domains.


I get why people hate on ORM's, but let's not throw out the baby with the bathwater here - I don't want to go back to the time where you had to write object definitions for each table the database, and manually sync them. Nor do I want to manually write trivial 'select name from foo where id=1' queries all day, and do all the plumbing to execute it. So when hating on ORM's and unnecessary abstraction layers, please qualify that with 'ORM's should not try to be too smart' and 'ORM's should provide fall throughs into whatever they're abstracting for non-trivial use cases', and not give people the idea to ditch ORM's all together.


> I don't want to go back to the time where you had to write object definitions for each table the database, and manually sync them.

Sure. Though I'd love if ORMs would seal autogenerated classes to prevent inheriting from them, language allowing, or otherwise prevent people from using generated ActiveRecord objects as their business model objects. ORMs should be just for creating an OO view into relational storage. They should not be running business logic. I know that people worry about having to write another set of classes just to wrap the ORM ones, but really, sooner or later (usually sooner) your business logic abstractions will stop mapping 1:1 to storage needs, and then you'll be wishing you had that extra layer of separation.

Or, in other words, treat ORMs as a more verbose and somewhat-compile-time-checked SQL. Nothing more.


I've had that problem, but frankly it was easier to make an hybrid (mostly ActiveRecord with a few "weird" classes that delegated their own storage) than to write a full Data Mapper layer.


Also, ORMs do more than replace a SQL statement. They compose together so when you have code like:

    person.orders.first 
And you change your database to make an intermediary table when business needs change and you need multiple people to be associated with an order you don't need to change the above line of code, you just call a class method in person and everything continues to work. It only gets more powerful with scopes and other things. I still drop into SQL, but usually when I'm doing data analysis, not normal business logic.


Why not make that a view or a stored procedure instead of keeping it as the ORM layer in the application code?


If you use this convenient syntax in many places, replacing it with views could result in hundreds of extra views in the database. Then you would have to maintain them whenever something changes.


There definitely is a reasonable middle ground. The best ORMs I have dealt with provide straightforward paths for simple queries and then let you drop to raw SQL for complex/performance critical stuff.


"Make simple things simple and complex things possible" - worth putting this placard on every ORM/API/DSL/GUI developer's desk.


I wrote almost that exact line in my blog post on the topic: "So a better ORM should make the simple things easy, and the hard things possible." https://blog.dieselpoint.com/a-minimalist-good-enough-approa...


Nor do I want to manually write trivial 'select name from foo where id=1'

You don't have too. SQL is brilliant for writing queries that generate repetitive, standard SQL queries.

Provided that the database vendor documents the system tables.


> const selectBy = (table, column, value) => db.query(`SELECT * FROM :table WHERE :column = :value`, {table, column, value})

> const selectOneBy = (table, column, value) => { const res = selectBy(table, column, value); return res && res.shift() }

Two or three lines gives you about 80% of the value in any ORM and avoids the -20% value found in the other 100k LOC.


> Two or three lines gives you about 80% of the value in any ORM and avoids the -20% value found in the other 100k LOC.

I have a hard time believing this when the two lines above are obviously wrong. You can't use :column to escape the name of a column in SQL. So your code has to protect it, which is not easy if you wan't to be portable. MySQL will generally use `column` but may be configured to use the standard "column".

Anyway, selectAllBy() and selectOneBy() are not enough to be confortable. I appreciate the static completion in Something.find({id: 1}).complete, the relative queries like Post.find({id: 1}).author, and many other things that help against typos, help code faster and make the code more readable.

I agree with the OP that fallthroughs are much needed, because writing custom SQL is sometimes simpler, and sometimes much more performant. Usually, its mostly about writing SomeModel.findAllBySql() which most ActiveRecord implementations provide.


[flagged]


Please don't cross into incivility when commenting here, regardless of how right you are or feel you are.

https://news.ycombinator.com/newsguidelines.html


That “smart kids say no to DSLs” meme is funny but also a garbage take if taken at face value. DSLs are important because specializing will generally make you / your tool more effective. Splunk has a special query language that reflects the product’s architecture. If you want to become productive with a piece of software you need to learn its language.

Edit: To clarify my position, Domain specific languages mean domain specific ideas. As soon as a product is no longer meant for general queries, but for queries over specific ki day of information in a specific kind of system, we can use that knowledge to make a powerful language in that domain.


I think splunk is a bad example. It's a really useful tool so the investment is worth it.

I've seen people crack out their hip looking graph-like DSL that they lay over the top of an Oracle database. It's crazy to do this. I know all this regular SQL so just let me use that as needed.


Programs should be written in languages that model them almost perfectly. Languages that are too powerful or too weak for the application means the programmer will make modeling mistakes and either leak abstractions or obscure them.


Perhaps it'd be better to learn/use eDSLs - that is - DSLs embedded in a general and powerful language such that interoperability between all the little eDSLs becomes painless. Examples of eDSLs would be lisp macros.


sklearn pipelines are an interesting model (specially in 0.20 versions with column selectors, etc) that could be implemented in wider context as a dataow language -- maybe with Prolog-like logic instead of ML data blenders.


More effective at what, other than using the DSL?

The article was about ORMs, not Splunk, and consequently their DSLs


serious question: what is the alternative as an interface to something like this that isn't a DSL? Is something that looks a bit like a familiar query language (like SQL) better? Is finding yourself in the uncanny valley of a language a feature or a bug?


They called Splunk out at the top of their SAAS list.


I think micro ORMs like Dapper are a perfectly reasonable compromise between too much abstraction vs too much abstraction. Hand populating data structures from database query results is error prone and tedious. Using a “big” ORM like hibernate or EF is a leaky and expensive (over-)abstraction. Not just because they typically come with a query dsl but they also come with performance considerations and architectural consequences that are hard to predict. You end up in a situation where estimating work is hard because you don’t know if the ORM is going to play along (making a feature trivial to implement) or hit a snag (making it very time consuming). With smaller abstractions the estimates may be higher in the best case but they vary less. This is one of the most important qualities about a library or stack. Not the average, but the variance in difficulty.

On the topic of query DSL’s - the only acceptable ones are those that are native to your programming language. A good example is the F# SQL type provider. If that’s sufficient for your needs, it’s actually quite elegant as far as query languages go - and it’s all F# meaning it’s not a specific language for querying.


I think that the current iteration of EF is still a great fit for small to medium sized projects. Besides offering strongly typed queries (LINQ) and updates, it also provides some additional functionalities such as migrations that such projects really can benefit from.


Thanks for pointing out the F# SQL, I just looked it up and read this

https://dev.to/kspeakman/dirt-simple-sql-queries-in-f-a37


I had to check the date because this could've been written 20 years ago.

Developers don't need other developers to tell them when or when not to use ORM. We know how it works. Some use cases are better for a quick inline SQL whilst others where you have hundreds of tables would lend well to ORM. It's not one size fits all and I'm sure we've all written a few apps in our time to know this to be the case.

And this idea you can just learn "one SQL" is pretty laughable. There is a subset of SQL that works across many (but not all) relational databases. But each database has its extensions which you really should be using to get maximum performance. ORMs automatically take advantage of these just to mention. And the behaviours you will get can differ immensely.


>I had to check the date because this could've been written 20 years ago.

And would have been just as correct.

Of course today people understand this better and distrust ORMs increasingly more, whereas back 10-15 years ago then it was the heyday of enterprise Java and all the ORM craziness.

At least we're also over the NoSQL fad too...


But each database has its extensions which you really should be using to get maximum performance. ORMs automatically take advantage of these just to mention. And the behaviours you will get can differ immensely.

But if you use vendor specific extensions you will have “vendor lock-in”. What if someday on a whim your CTO decides to change the database your entire multi billion dollar organization from depending on Microsoft/Oracle and wants to go open source?

Yes I’m being sarcastic. In reality, statistically no company makes those types of sweeping changes because the risks are too high and the rewards are too low.


Company may very well not have a choice. A couple of weeks ago a customer requested Oracle instead of MS SQL - now somebody is looking into all places checking if SQL is good enough.

To me the saying "ORM is a Vietnam of computer science" rings true too often. Somehow projects which I deal with don't really benefit from ORM... so I could live completely with SQL alone.


If I were writing apps that were sold to customers, that would be even more of a reason to use LINQ - not most ORMs though.

I know about a software package that was written in C# that officially supported Sql Server,Oracle, and Mongo and he was able to support all three with basically the same codebase using Linq and runtime translated Expression<Func<T>> statements.

His LINQ queries and expressions were the same across data stores.


It never made sense to me how popular ORMs were. The very first time I used one, I understood straight away that it was a bad idea and I never changed my mind about it (though I tried).

Why is it that open source software which adds unnecessary complexity and slows down development tends to become popular but open source software which takes away complexity and speeds up development tends to not get any attention. It's like there is some kind of conspiracy.


I feel the same way about most ORMs - except for LINQ. C# treats queries as first class citizens. There is something very powerful about being able to have a method in your repo...

public List<Customer> Find(Expression<Func<Customer,T>> expression) {...}

and then your client can use any random expression...

Find(c => c.age > 18 && c.age < 65 && c.gender == “M”)

and have that expression translated to either SQL, MongoQuery, or anything else that has a LINQ provider.

If done correctly, not only can you switch between RDMSs, you can switch between an RDMS and a Nosql data store without changing any client code.

When you are writing your unit tests, you can use in memory Lists to mock your data store and still test all of your queries without using a database.

Of course you also get type safety, autocomplete, and in the case of NoSql data stores, you enforce a schema over a schemaless data store and get to work with strongly typed objects.

I’ve never seen any purpose of an ORM outside of LINQ. They just add another level of complexity and still don’t integrate with the host language naturally.


I feel the same. In addition to the ORMs, yet another super irritating thing is writing HTML in server side languages like Ruby, PHP etc in the frameworks. It is perfectly possible to just write plain HTML in views and partials and still keep the code clean. Instead, I've to learn yet another un-natural way to write HTML.


ORMs are really useful when you want to pull your data in a deeply nested format that a junior developer can work with easily. Manually nesting table rows is tedious, and stitching together data on the fly requires you to understand the complete data model, which might be outside the purview of some developers.

I should be clear though, from an architecture standpoint I think it's much better to go straight to SQL, and keep the data unnested. Like anything in life, it's a trade-off. It requires more up-front data model knowledge and more up-front work, but it's much easier to debug, more flexible, and performs better.


When I was a junior, I could write my queries in SQL in 30 minutes for the report which was asked from me, but I needed two more days to figure out how to do it with the ORM.

For juniors, it's best to have a less abstractions.


webpack and the entire "modern" js frontend...

all because of an inability to manage versioning change across the standard browser js api...

great for a giant megacorp looking to waste money on busywork and divide the workload across more employees (front-end devops?!?)

less useful when you already have to compile a backend, don't really have a problem with ES5, and understand that you are basically only tasked with making your dom updates dependent upon data model changes, YMMV


so because you don't see the obvious problem with being stuck on a single version of anything forever, webpack, representing progress in this case, is bad? nice try

what does versioning has to do with bubbling, wtf?


>so because you don't see the obvious problem with being stuck on a single version of anything forever, webpack, representing progress in this case, is bad?

In fact, the parent does see (and called) that "obvious problem with being stuck on a single version of anything forever".

That's why he doesn't cheer for the band-aid solution that's webpack and doesn't thing it "represents progress".


I disagree with the ORM hate generally, being a massive fan of ActiveRecord for making it easy to build queries and still drop down to SQL as required.

But I’m right on board with the “stop inventing rubbish pseudo query languages” idea. I’ve rarely seen an example that wouldn’t be better if it were it just “SQL subset with some additional features”.


XPO (Devexpress' ORM for Windows) fan here; I've used this for years to deliver solutions for a number of clients, and it's still possible to use SQL directly in the few percentage of cases where it's necessary. I'm afraid I've given up reading arguments against ORMs as none of the cons seem to have any relevance to the work I do now or will do in the future, but I admit I am a 'enterprise' developer / consultant.


I've worked on large projects using ORMs and others using parameterised SQL strings. My experience, FWIW, is that the advantages listed in the article are all real, on top of which there are some more esoteric SQL features (like window functions) that may not be well supported by a given ORM.

On the other hand, there is a significant cost in terms of duplication. In ORM code it is trivial to decide a where clause at run time. Not so much in plain SQL. So you end up with a lot of copies of the same query, or else some sort of query assembly layer, at which point you're halfway to an ORM anyway. I am undecided on the issue.


I'm convinced there are two classes of ORMs. Those that try to abstract the relational model and those who are the relational model.

The former category includes things like Django's ORM: very limited in what you can do, it doesn't actually "get" SQL, mismatch between the ORM API and the database. The latter category includes fewer software; sqlalchemy is my familiar example. Because sqlalchemy does not abstract the relational model, instead mapping it into your application language, it has ~few mismatches between its API and the database.

The former category is what "kinda works well enough for CRUD apps and I don't need to know anything about nothing" and then become a major problem, the latter category presumes you know how SQL works but then allows you to work.

Random snippet just because I feel like it.

    def all_children(self):
        cte = session.query(Tag).filter(Tag.parentid == self.tagid).cte(recursive=True)
        cte = cte.union_all(session.query(Tag).filter(Tag.parentid == cte.c.tagid))
        return session.query(Tag).select_entity_from(cte).all()


I tend to refer to the latter as ROMs. Ruby's Sequel is also somewhat this. My (perl5) DBIx::Class is somewhat this (modulo all the design mistakes).


SQL reasonably standardized? You can't even write hello world without running into vendor differences. Microsoft has SELECT TOP FROM, while Mysql has SELECT FROM LIMIT.


And yet LINQ seems to be so popular...

Of course some standardisation amongst ORMs would be good. That would also help them be less "garbage".


LINQ is more than just an ORM. Linq is just as it’s name implies a built in way to standardardize querying across a wide range of domains. It just translates your embedded query statements into expression trees that a third party can do with what it will. The Mongo LINQ driver for instance is excellent.


I really like LINQ, and I generally also tend to prefer LINQPad over SQL Management Studio for simple DB queries/lookups. It has the extra benefit of allowing me to mix declarative LINQ based queries with imperative (C#) code, making it easy to do things like quick data cleaning/transformations, merges/joins with external data etc.


"Let’s dispel with the myth that ORMs make code cleaner. Join the embedded-SQL movement and discover a much more readable, much more straightforward way to query databases."

Any argument whatsoever for this? Would love to see an example of how when you do away with the whole object persistence layer, and you just have a SQL string (which ORMs allow you to do anyway), how do you get your parameters over, how do you get your rows back, how do you manage your transactional scope, how do you get your rows in and out of your objects? all of which has nothing to do with a SQL string.

Well let's read on:

"Erik Bernhardsson... is the CTO at Better, which is a startup changing how mortgages are done. I write a lot of code, some of which ends up being open sourced, such as Luigi and Annoy. "

Open source stuff! Let's go there and see an example of this "write raw SQL and don't use any persistence libraries and your code is readable and straightforward", because nobody ever seems to actually want to illustrate this and how they don't end up writing their own ORM anyway, and we see, oh https://github.com/spotify/luigi/blob/master/luigi/db_task_h..., it's SQLAlchemy ORM.

Foiled again in my search to see this elusive super clean and simple raw SQL with no ORM that doesn't reinvent an ORM anyway. Which is the real "myth" ?


Check out Rosetta. Its what we use at HubSpot.

https://github.com/HubSpot/Rosetta

Its by far the best Object <--> Sql layer I've ever used. You manage your objects in Java like you normally would and then Rosetta maps your objects to columns in your SQL DB using Jackson. This means you can write plain ole SQL for very clean simple code. When it comes time to get data out of the DB it again uses Jackson to map the results back to objects in Java.

I was super skeptical at first, but it makes reading/writing data out of a SQL database super simple, while encouraging very simple explicit sql.


I’ve used Clojure’s hugsql[0] and C#’s dapper and petapoco[1]. I rather liked the result. You don’t generally build dynamic strings (though sometimes you do). You generally write parameterized SQL in a fairly straightforward way with these. Honestly, SQL + Clojure is a great combo. Datalog + Clojure is even nicer.

[0] https://github.com/layerware/hugsql

[1] https://github.com/CollaboratingPlatypus/PetaPoco


To be fair, he didn't write the code you're linking to. Luigi has a lot of contributors. I was a pretty heavy contributor/user for years and I was never able to get the task history feature to work.


sure. but seriously. "Can we just dispel with this myth about ORMs?" What myth? can you provide any evidence or argument of any kind? How about if I said, "Can we just dispel with this myth that Erik Bernhardsson has any idea what he is talking about"? (to make it clear, this would not be a fair statement either because i know nothing about this person) and just ended the blog post there. Because I actually looked at his own open source projects for evidence of this deep wisdom he has and found none. not a very high quality post.


He provided an argument. It's the 4th paragraph of the blog post, ending with "and I end up with bloated higher level data classes rather than easy to understand tuples or dicts that contain the data in a dumb simple format that is trivial to introspect."


That is in fact not an argument about ORMs and especially not about DSLs, that would be an argument against object oriented programming overall. Where again, let's see the examples. When you write enough tuple business logic in a non-FP language you get into a new set of problems with code organization. And you still have to marshal those tuples in and out of SQL statements in a way that makes sense vs your transactional scope and there's a lot to think about there.


It's about how ORMs result in less clean code by forcing a clunky generic OOP paradigm on any DB interaction. You may not agree with this argument, but it is an argument.


one lazy sentence with no examples does not allow you to declare "Let’s dispel with the myth that ORMs make code cleaner. ". Make an argument, show examples, be specific. For example. I don't like Python's asyncio. I don't just blog, "can we just dispel with this myth that asyncio makes code faster?" and just bask in my upmods. I made a very well researched and tested argument and spent many hours making sure, if I was going to make a statement like "technology X that tens of thousands of you use every day is a myth", or more accurately "not quite as worthwhile as you might think", I took the time to thoroughly illustrate this: http://techspot.zzzeek.org/2015/02/15/asynchronous-python-an... Whether or not people agree with what I wrote (though nobody seemed to really disagree much), I'm not just trolling for upmods, I'm making a tangible contribution to the subject. What this person posted is basically non-debatable because no debatable points were made. Those of us with a lot of time invested in DSLs and ORMs would prefer a real discussion with real things we can debate, not just who can rant more loudly. I can debate this blog post very simply that there's tens of thousands of developers who use DSLs and ORMs to great success every day and the burden of proof is on this poster to prove them all wrong.

This is just a very low quality rant that appeals to base cheerleading instincts from whoever happens to agree with this person already, and I will choose the vast community of working software over this post in order to determine what exactly is a "myth".


It wasn't one lazy sentence, it was a paragraph. I don't think he was claiming that you can't use DSLs or ORMs successfully. This is just a quick opinion piece. Not all writing needs to be a thoroughly researched debate defense.

I personally didn't already agree with what he wrote, but there was enough in it to make me think about the topic a little more and shift more toward his position. I already know what ORM code and raw SQL calls look like without him providing examples.


> I already know what ORM code and raw SQL calls look like without him providing examples.

I do too and code that not only uses raw SQL (not that big a deal in and of itself) but also reinvents the whole persistence layer (which is the whole part of "ORM" that has nothing to do with writing SELECT statements or using DSLs) is a complete mess.

I really want to see the examples so I can learn from them and perhaps have it contribute back to my own ORM project (SQLAlchemy).


I use Dapper [1] at work, along with lots of hand written SQL. All the SQL is in a single data access library, which is easy to both mock and test in isolation (there are several tests that run against a real database mainly for some of the more complex queries).

You write regular SQL, can easily parametrize everything, and get collections of objects back. And it's very fast.

[1] https://github.com/StackExchange/Dapper


That's an ORM.


Try Norm, https://github.com/dieselpoint/norm. I wrote it to solve one problem: get rid of all the boilerplate that JDBC requires. Beyond that, it maps tables to pojos, or to Maps and Lists, if you prefer. Minimalism is the way to go: https://blog.dieselpoint.com/a-minimalist-good-enough-approa...


"Would love to see an example..."

Delphi has always had a default non-ORM dataset layer (there are ORMs for it), and it works like this for queries:

1) There's a base TDataSet class (Object Pascal uses "T" to denote "Type") that handles all abstract column and row storage and manipulations, with no pre-disposed notion of how to actually load such rows. Dataset columns are abstracted away also, and provide a lot of automatic type conversions and functionality like BLOB column stream access. Having this base class allows disparate descendant classes to easily interact with each other without knowing the details of how the data got there. All query objects descend from this base class, and fill in all of the functionality for actually interacting with the database server/engine.

2) For query objects, the SQL string gets assigned to a query object property (typically called "SQL"). Parameters are specified as named parameters by using colon notation (:Parameter) instead of "?". During this string assignment, a property setter method parses the SQL string and automatically sets up the parameters as a collection that is another property of the query object. These parameters do not have any type information assigned to them at this point. The developer can choose to just manually assign values to the parameters using type-specific parameter properties at this point. Any type differences are managed by the underlying object, so assigning an integer to a string parameter will result in an automatic conversion.

3) If you manually prepare the query object using a Prepare method, then the SQL is sent over to the database server to be prepared and any type information about the parameters is sent back from the database server to be assigned to the parameters collection (depends upon the database server). If you don't manually prepare the query, then it is automatically prepared during the query execution (4).

4) The SQL is executed using an Execute or Open method. If the SQL is a SELECT statement, the query object is automatically populated with the rows and the rows are managed using the base TDataSet functionality. There are methods for navigation, updating, etc. and updates of non-directly-updateable result set cursors are managed by the query object. Query objects are linked to database objects, and the database objects manage the transactional scope for updates. You can also use such database objects to execute one-off SQL statements where the only thing you're interested in is the result set row count or the affected row count.

The interesting part is how Delphi handles static-typing of result set columns in your application. In the IDE, you can right-click on any query object and have it automatically populate "persistent" column objects whose class type reflects the underlying result set column type. This means that if you try to access or assign the column object's raw Value property, this access/assignment is subject to type enforcement by the compiler. However, you are free to use other properties that perform type conversion, in which case you'll get a runtime exception if the type conversion fails for any reason. You can also assign names to these column objects, allowing you to write easy-to-read code like this:

   OrderCustomerID.Value := 1000;
So, you can get a lot of the benefits of an ORM using an architecture like this without having to sacrifice the flexibility of manually-constructed SQL statements. A lot of this depends upon the peculiarities of the Delphi component library and IDE, though, so how transferrable this to other environments is an open question.


I forgot to mention: you can also do cool stuff like link query objects together so that when you navigate in a parent query, the parameterized child query object is re-executed with the new parent query column values. This way you avoid N+1 queries by only executing queries when you actually need to see the rows for the child query object.


Meh. If the backing store is not SQL, why would a SaaS provide a (much harder to implement) SQL layer with all its standards (92, 99, 2003) and quirks instead of writing a (probably) much simpler custom query language?


I think what he's asking is that people allow a flat file export, which you would have to map and import yourself. This seems reasonable to me.

And I agree. I wasn't involved in writing NRQL but statistics queries at New Relic during my time were already approaching turing completeness, so it was just a matter of time. Timeseries data in particular really doesn't map well to SQL at all, sadly, as a SQL fan working with a lot of timeseries data over the decade+ now.


Some companies do allow flat file export.

Others don't because sometimes it's not that simple to fetch all of the data to give you with one click. Many of these companies are just rolling up the metrics in some online database and hiding the original files away in cold storage.


>I think what he's asking is that people allow a flat file export,

I don't get this though. If you want to export your data as some flat file, why use MixPanel at all? Just store the events in your own database and query it yourself. Why pay the cost of both solutions?


Why does it have to be either SQL or a custom language anyway? We have developed many generic query languages for various different structures [0].

[0] https://en.wikipedia.org/wiki/Query_language


Shameless plug here, but this is exactly the reason why I did not create a query builder in the RedBeanPHP ORM. At the time (2009) query languages were a real 'hype' (as well as noSQL) but I have always loved SQL and I struggled with all the SQL-alternatives offered by other ORMs. So, when I created RedBeanPHP I decided to complement SQL rather than trying to replace it. Yes, there is some room for improvement, notably in the integration with the programming language (in my case PHP). So the ORM class has some methods to indicate you would like to apply a condition, but the condition itself is just written in pure SQL.I see my ORM more as a bridge between SQL and PHP than a carpet that hides the SQL.

Not all DSLs are necessarily bad though. Personally I like to create some very basic and straightforward DSLs to replace horribly complex GUIs with tons of nested menus (aimed at professionals). I think DSLs can be useful for educated computer users who don't know SQL (like people in finance, medicine, statistics). Also there should be a limit to the complexity of a DSL. Not every DSL needs to be turing complete. Simple DSLs that cover the required functionality are the most successful in my experience with customers.

However replacing SQL just does not feel right, it's already an awesome language to query a relational database so why replace it? So, for the most part I agree with the author - although I miss the nuance a bit.


I loved redbean, such a nice library.

Don’t do much php nowadays but Django is a great db - object abstraction. You can go raw sql if you want quite easily.


This reminds me of something that happened in a previous gig where our team was working primarily with SQL. The company rockstar one-day decided to rid us all of our perceived misery by introducing a REST interface over our existing databases complete with it's own query language that he managed to foist upon us with the clout he had with upper management. The query language was limited at best even when compared to some of the examples in the article. Initially all it provided was basic matching against several columns and the ability to do rudimentary paging across resultsets. Naturally we had problems with this as a big part of our job was writing reports relying heavily on joins and aggregation - we were left in a situation familiar to anyone whose used NoSQL joining everything in code but without all of the niceties that come with maturity. It's a given that team productivity and general morale took a bit of a dive at this point.

My current theory to the proliferation of these query languages is ignorance. Aside from a severe case of NIH the developer behind our query language exhibited a flawed understanding of SQL. If you're planning to roll your own query language you probably shouldn't without first considering SQL, your intended users and the use cases that they're trying to satisfy.


Initially all it provided was basic matching against several columns and the ability to do rudimentary paging across resultsets. Naturally we had problems with this as a big part of our job was writing reports relying heavily on joins and aggregation - we were left in a situation familiar to anyone whose used NoSQL joining everything in code but without all of the niceties that come with maturity. It's a given that team productivity and general morale took a bit of a dive at this point.

Yes being forced to use a REST interface over reports is a bad idea but that has nothing to do with joins over a NoSQL data store.

Mongo does joins via the $lookup function and the C# Mongo driver will translate the LINQ code to MongoQuery for you.

https://www.axonize.com/blog/joining-collections-mongodb-usi...

Worse case even if you do get data sources from separate places, it’s just as easy to do joins on two lists as it is to do in Sql using LINQ.


This sounds all too familiar. Developers having a REST epiphany and thinking they're clever by mapping relational rows to REST resources is also very common with Spring apps (Spring data in particular).


I agree with the author's sentiment, in the context of relational databases. I can't get back the time and effort spent porting SQL to query builder and/or orm syntax. The best I can do is learn from my lapse of sound judgment and instead use parameter binding against raw SQL and never interpolate strings of SQL.

I regret not adopting this practice sooner.

Most of my substantial work resides in that raw SQL feature. So, I use a library that offers good support of that.

I have written hundreds of SQL using query builders and ORMs.


Every ORM (and I mean every one) has the ability to let you either (a) use raw SQL, (b) use raw SQL interpolated with column names or (c) has a syntax which is very close to SQL.

Porting should not have been some onerous or career destroying activity. As Job would say I think you've made a huge mistake.


Those who don't learn from mistakes will repeat them. I've learned from my mistakes and share a lesson today.

Most of my substantial work resides in that raw SQL feature. So, I use a library that offers good support of that.

I have written hundreds of SQL using query builders and ORMs.


If you mean the character voiced by Bojack Horseman in "Arrested Development", it's spelled Gob.

Amazing how they got Bojack into that human costume.


Great, so force SQL to 'join' things that aren't tables and 'select' things that aren't rows.

SQL wasn't built for querying every possible data store.


Yeah, that was my reaction as well. I fully understand his point regarding ORMs that are meant to be an abstraction over a relational database, but imposing the relational model over non-relational datastores sounds like a disaster.


If only there was a popular example of this. Wait there is: PostgreSQL.

They bastardised SQL to support JSON data types just like every other vendor has to do because SQL is for relational and only relational data stores. Is this the utopia that the author is after ?

https://www.postgresql.org/docs/9.0/static/hstore.html


I thought they were, for the most part, fairly logical extensions to SQL.

You don't have to use the JSON/JSONB column types, they are optional.

We use them extensively in production and haven't had much difficulty learning them.


There are reasons different programming languages exists. And so as query languages. Different stacks, different ways to handle, optimize and accelerate queries over structured (SQL) and unstructured, schema-on-the-fly (SPL) datasets.

If you don’t want to learn - it’s a personal choice.

You can ride a bicycle that works everywhere while others prefer driving sport cars on a highways.


To avoid obscure ORM syntax and resulting garbage queries, as well as cumbersome inline SQL blocks, just implement your complex queries as stored procedures / views etc.


Amen. You can also declare those stored procedures SECURITY DEFINER and deny access to the underlying tables to the client role for much Better security. For example if you have a table of users with login and hashed password, a check_login stored procedure allows checking password but if(when?) the app server gets compromised, the attacker can't even dump the list of valid logins because they don't have SELECT privileges on the table.


Careful, this advice is dangerously close to proper DBA knowledge.


Having a dependence on stored procedures is a disaster from a devops perspective. Having all of your logic in your code makes deployments, rollbacks, testing and everything else from a development standpoint much easier. Having one source of truth for your code - your repo is much better. I know that if I check out code from three weeks ago, it’s the same code. I don’t know that if the code is dependent on stored procedures.


To call them a nightmare is an overreaction. Client-exposed stored procedures can be versioned either by name or by the schema they're attached to.

Additionally, you're making sweeping generalizations based on a limited perspective. Loading up the application layer is the right choice when your data will only ever be consumed by that application, and multiple versions need to coexist. When you're talking about data that cuts across a business, and where a single application version lives at a time, loading up the application layer is infeasible and unnecessary.


To call them a nightmare is an overreaction. Client-exposed stored procedures can be versioned either by name or by the schema they're attached to.

So now we have something like

CreateCustomer_1

CreateCustomer_2

CreateCustomer_3

And different apps are using different versions. If you have to make s change. You have to make a change to every version because you don’t know which app is dependent on which version.

What changed between the stored procedures and what code commit did they go with? Who changed it? (Usually this is solved very badly by having headers with comments that go back years). I can do a “git blame” on code, diffs, etc.

Loading up the application layer is the right choice when your data will only ever be consumed by that application,

Ideally, it should be one service per domain that is responsible for one set of data. That can be either a microservice or a module in a mono repo.

Of course reporting would be separate and would cross cut multiple domains and would usually have intimate knowledge of the tables anyway.

It’s also much easier/cheaper/faster to scale app servers than DB servers.


You can keep your sql in version control and use a script to reconcile the current database schema with the contents of a repository easily enough. Then you can track, git blame and in some cases, easily revert. Check out Alembic on this front, it's pretty useful.

If you're going back and changing old versions of a stored procedure, you're doing it wrong. The only case where this would be true is a breaking schema change, and then application layer code would break too, so the point is moot.

Siloing your data makes it less useful (or rather, it increases the cost of using it) and less discoverable. Additionally, if you have some sort of security model in place on your data that becomes exponentially harder to manage in the silo'd case.

As for scaling - read scaling databases is REALLY easy. I admit that write scaling is more challenging, but stored procedures are read-dominant in general. For specialized or very high throughput cases, custom application layer logic can be made much computationally cheaper, but this requires more (and more expensive) engineers, so that must be factored into any potential savings.

Siloing and thick application layers are great for some use cases. Data aggregation and thick database layers are great for others. Insistence on one model in all cases is only going to limit you as an engineer.


You can keep your sql in version control and use a script to reconcile the current database schema with the contents of a repository easily enough. Then you can track, git blame and in some cases, easily revert. Check out Alembic on this front, it's pretty useful.

And what happens when I need to rollback? I have to rollback the stored procedure code separately. What about regression testing?

If you're going back and changing old versions of a stored procedure, you're doing it wrong. The only case where this would be true is a breaking schema change, and then application layer code would break too, so the point is moot.

It would be one change in one module (in process) or one microservice (out of process).

Siloing your data makes it less useful (or rather, it increases the cost of using it) and less discoverable. Additionally, if you have some sort of security model in place on your data that becomes exponentially harder to manage in the silo'd case.

For reporting/analytics that would be a separate longer running process anyway and wouldn’t be a part of your OLTP system anyway and you probably wouldn’t be using stored procs. You would be using some type of reporting system.

As for scaling - read scaling databases is REALLY easy. I admit that write scaling is more challenging, but stored procedures are read-dominant in general. For specialized or very high throughput cases, custom application layer logic can be made much computationally cheaper, but this requires more (and more expensive) engineers, so that must be factored into any potential savings.

Yes, throwing up read replicas is just a matter of throwing money at the problem - and I’m not morally opposed to using money as an optimization technique when necessary. But you can still get more granular scalability with app servers.

For specialized or very high throughput cases, custom application layer logic can be made much computationally cheaper, but this requires more (and more expensive) engineers, so that must be factored into any potential savings.

And that’s where I come in :)


This was what I was thinking also.


I really really like what jOOQ has done for SQL under Java (and other JVM languages). It's basically a type safe interface to SQL that anyone who knows SQL can grok in minutes and it provides constructs to help bridge the gap between SQL and the programming language. Among other features it has tools to help migrate between different databases (and more are planned) - something that is usually considered to be a strong point of ORMs.

I've used a couple of ORMs and jOOQ blows them all away easily. It's not the first product that tried this approach but jOOQ does it really well. I've partly or fully converted at least 3 Hibernate projects to jOOQ and all my recent JVM projects use it exclusively. In my opinion products like jOOQ make ORMs redundant for most use cases.


> "It’s not like people learn an ORM instead of learning SQL anyway."

BWAHAHAHAHA!!! No. I have to use ORMs at work because they are forced on me. Same thing with Eclipse, and GWT, and a million other things that I detest because my employer has structured their development processes around hiring average talent and getting average(ish), repeatable results (I'm serious, I work with a lot of developers who only know how to code in Java, in Eclipse -- it's maddening). I'm the malcontent who doesn't fit in because I say things like "Let's just use SQL." or "I promise you, this architecture is not scalable, regardless of your seniority over me."


This resonated strongly with me. Almost all of the heavy DB interaction projects I've done in the last couple of years - be it in Python, Go or Java, the SQL layer has almost always been raw queries going to the DB. Makes things so much easier.

I don't miss SQLAlchemy where I would trawl through documentation to figure out how to do X or Y.

As for SQL standardization, +1 to that. Learning a new pseudo-SQL is only fine if there are additional features on top of the DB, but I've encountered databases where the SQL support was present in the name only and extremely limited, with people making do with UDFs in order to achieve basic things.


I’ve had the same experience, and as soon as the interaction became very complex (multi table, multi row updates) we just moved it all into stored procedures.


Never understood what's the thing with stored procedures. You soon find that an indeterminate amount of your business logic is written in stored procedures, and in an opaque language that is fit for manipulating data, not for implementing business logic; not to mention the annoyance of running updates on the database, which works ina fundamentally different way from deployable code.


what it usually means is, "we gave the DBA the job to do and now we don't deal with it at all"


Also, learn just one programming language. Lisp obviously.


Unironically this. I feel like a zealot saying it but having eDSLs with painless interoperability makes lisp a joy to work with.


I’m surprised no one yet had mentioned Facebook’s osquery tool. Even though most things aren’t relational databases, a uniform way to query them and join different datasources together is a very powerful idea.

Using sql to query a whole bunch of stuff has been very nice.

I just wish the excellent TablePlus client could use osquery under the hood to show a lot of system level things in a nice pretty UI.


Mongo is one of the most painfull, it's inconsistent, simple queries take dozens of $ and { }, and the db.tablename.<...> is annoying.


OP's frustrations are quite understandable but I can think of a couple of areas where ORM-like concepts have worked well. PyDAL[0] and Linq are both incredibly expressive and PyDAL is also low overhead (it's not an ORM, it's a data access language, which means it doesn't have the baggage of an object-oriented layer).

Another reason to use a DAL like PyDAL is that, properly written, it can abstract away the data layer such that you can switch from (for example) MySQL to PostGres to Google Cloud SQL with essentially no retooling required.

Finally, using a DAL can help keep inexperienced programmers on track with security, accessibility, and performance requirements.

[0] https://github.com/web2py/pydal


> Finally, using a DAL can help keep inexperienced programmers on track with security, accessibility, and performance requirements.

This is a sure way they'll never learn the real thing. I know since I'm sitting next to a (young but talented) guy who knows only Spring and JPA, and freaks out all the time because the developer of the legacy system had dared to assemble SQL queries manually in the code (which are complex enough I personally hadn't bothered using JPQL in a trial-and-error development model either).

Wasn't the post exactly about not wasting novice and other developer's time with crap criteria APIs and such? Just compare the sheer size of the SQL spec or reference manual against the shallow description of JPQL to judge which language you should be using for a project with any kind of depth.


The custom query language I find most annoying (possibly just because it's the one I deal with the most), is JPQL, the query language of the Java Persistence Architecture. JPA explicitly targets relational databases, so there's no obvious reason why you couldn't just use SQL. You might think the advantage of a custom query language would be that it could abstract over differences between SQL implementations, but JPQL is underspecified and just gives you the underlying database behaviour in many cases. I spent a day trying to figure out why my tests passed but the staging environment was claiming that 0 was greater than 0; turns out there was a difference in rounding behaviour between the in-memory database used for tests, and the real database, which JPA was cheerfully glossing over.


I still yet to find sane JDBC wrapper library for Java. JDBC itself has terribly verbose API. And any popular library I've encountered is not very nice to use. I end up buliding half-baked JDBC wrapper for every project I'm writing. And Hibernate at least have good enough API.


This is how SQL injection makes a comeback. No thank you, I'll stick with my orm.


SQL standard defines a couple of special characters within strings - like ' and * . Not too complex. If you escape input - say, using a library function - you won't get injection problem.


He forgot the Jira Query Language. To be fair, it really works!


I was so mad when I wanted to make a simple filter on Jira tickets and I had to use "JQL"...


In my experience ORMs work well for smaller projects and at the beginning. Once the code matures, it is much more performant and simpler to use direct SQL.

One thing that really resonated with me from the article is the following:

> Every SaaS product should offer a plug-and-play thing so that I can copy all the data back into my own SQL-based database (in my case, Postgres/Redshift).

Totally agree, a data dump should really be a standard feature (and not take ages to produce either).


Having written assorted data layers: If you can't replace a generated query with a chunk of literal SQL when optimisation or raw power indicates it's the best option, the data layer sucks.

Sadly, being software, "the data layer sucks" is true of most data layers.


Erik may know SQL but there’s an entire generation of developers who don’t.

These developers find it easier to dip into shallow DSLs instead of learning the depths of SQL.


If they can be developers, they can learn SQL. Apart from DDL statements, it's literally 3 DML statements, of which most of the clauses operate exactly the same way across all 3 statements.


Sorry, that should be 4 DML statements...


> I just want my SQL back. It’s a language everyone understands

I'm sure lots of people do understand SQL. But if you started programming post 2010 it's entirely possible you've never had to deal with a row database. My case:

- GAE datastore

- MongoDB

- RethinkDB

Again not discounting those who've been programming longer, it's just that JSON-stores are becoming default and the amount of people who don't know SQL is probably more than you think.


I really loved rethinkdb rql. Was a very elegant language to deal with json datastores over mongodb


SQL is syntactic sugar for first order logic. It is much easier to query relational database with SQL than abstracting relations with ORM.


How is

“select * from customer where age > 18 and age < 65”

Any more of an abstraction and easier than

from context.Customer where c.Age > 18 && c.Age < 65

With one it’s a magic string where you could have typos. With the other you get compile time syntax checking.


If you use a modern IDE and extract your SQL into separate files you can get syntax checking, and even the ability to run the query on-server directly and get a table of results in a table-formatted tab with a single click. How much do you have to do to get your ORM to run your query, and are the results as easy to work with?


With LINQ (I hate most other ORMs) you get objects back and you use the same query syntax for working with RDMS’s, NoSql data stores, REST APIs, in memory collections, etc.

If you had an in memory list you would write:

var seniors = from c in customers where c.Age > 65

If you were using an RDMS you would write:

var customers = context.Customers

var seniors = from c in customers where c.Age > 65

If you were using Mongo you would write:

var customers = database.GetCollection<Customers>(“Customers”)

var seniors = from c in customers where c.Age > 65

In each case, the query would be translated appropriately - as in memory code, SQL, or MongoQuery respectively.


I understood your SQL example but I don't understand your counter example.


The second is LINQ within C#


You must not use good SQL IDEs...try Datagrip.


Sql is part of my code that doesn’t help....


I agree, say no to garbage query languages, including SQL. Datalog has been a thing for aeons, why not use it?


Aggregation is awkward. It is not that composable. Sub-queries are not a thing. Prolog conventions make things awkward. The ammount of datatypes seems to be limited.

If you encounter datalog in the wild it will be something pretty-custom, like datomic, pydatalog, or even differential dataflow (that feels more like map-reduce with fix-points?)


>> Prolog conventions make things awkward.

Hey. What do you mean? Which Prolog conventions?

(I write a lot of Prolog and I'm always curious what other people think about it).


Maybe I haven't used datalog enough, but the convention of lowercase data, uppercase-starting Variable strikes me as limiting.


Was going to write a comment about datalog but will piggy back on yours. Every query language has felt like garbage to me until discovering datalog. So simple I explained it to my non technical business partner and he grasped how to query things within five minutes.


This is some A+ bah-humbuggery. You want companies to parse sql and translate that to backend api calls? What a nightmare. Data isn’t always co-located, and not all data is allowed to be fetched together (eg, protecting user privacy in Google Analytics).


This is why I really like JOOQ for Java. Its ORM but with SQL. Best of both worlds IMHO.


jOOQ is my favourite Java library. The code generation effectively extends type checking down to the db types and makes it easy to build your persistence layer without messy object mapping... if used properly; I've seen some setups that misused jOOQ.


I'll be happy to write my own SQL (I do for complex queries) but I don't want to extract results manually from results and tweak the code every time I change the schema. At least those parts of ORMs must stay.


I believe that sqlx for go is amazing in bridging the gap between orm and plain SQL!

https://github.com/jmoiron/sqlx


That does almost nothing... I enjoy writing SQL and Go with sqlx, but testing other designs/ideas becomes so slow compared to Python/Django.

I'll be using Gorm on my next project, because life is so short..


And I’m assuming your toolbox just contains a hammer? Granted, there’s a lot of duplication of effort around, but in many of the examples you cite they are trying to solve different problems.


There's a claw hammer, ball pein, mallet, bronze hammer, rubber hammer if you don't want to band your head on the table, and of course the mighty sledge hammer.


So just hammers :)


I've used Hibernate's HQL for many years but now I've started using raw SQL in my Java microservices with libraries like JDBI.


Agreed on using SQL under the hood for every system, but I don't have a problem with ORMs.


Just to go slightly off-topic, but anybody here felt it would be a dream if Excel allowed pure SQL instead of those absurd formulas like "sum if" etc?

(I believe that it's (relatively) recently become possible to define tables as SQL data sources, not sure how practical that is or if it's used at all.)


"define tables as SQL data sources" ?

Excel can query external data sources with SQL queries, and pull the results back into the spreadsheet.

And via ODBC you can use .xls files as data sources, and query them with SQL style syntax from other programs. (I don't know how far beyond the basic "SELECT [Column Name One], [Column Name Two] FROM [Sheet One$]" it can support).

Both of those date back - https://www.connectionstrings.com/microsoft-excel-odbc-drive... - most look like Excel 2000 or Excel 97.




Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact

Search: