Live data from Hacker News

What ORMs have taught me: just learn SQL (2014)

wozniak.ca

411–420 of 654 posts

Re: What ORMs have taught me: just learn SQL (2014)

#411
post #400

Earlier quoted context omitted.

ORMs that I've experimented with tend to fall into one of two categories: either they treat the object model as prime, or they treat the relational model as prime. The former almost invariably spurt out inefficient queries, or too many queries, or both. They usually require you to let the ORM generate tables. If you just want to have your object oriented design persist in a database, that's great. The latter almost i…

I think you may have only experienced bad ORMs then? All an ORM needs is a mapping between database fields and object properties so a good ORM should allow you to separately define a mapping between your object model and relational model so you retain full control of both. > it encourages you to write too much data manipulation logic in code rather than directly in the database I find doing too much business logic re…

Whereas I find doing too much business logic related data manipulation not performed by the database to be an anti-pattern that creates significant risks with testing and a source of data bugs.

My model of thinking is that any copy of data that isn't currently resting in the database is potentially stale; avoid round trips like the plague; get new data into the database as soon as possible.

For me and the way I work, it's less about good vs bad ORMs, rather more often a question of whether I even want my data hydrated into a special object at all. I've come to the realisation that for the kind of work I do, data objects almost always end up being an unnecessary layer of indirection that don't give me any real benefits—and they change the way you think, because every transform becomes an opportunity to write a method on an object and not a straightforward query.

Re: What ORMs have taught me: just learn SQL (2014)

#412

I too have gone back to SQL after working with ORMs for 10+ years. Having worked with them on a wide range of projects and teams, I can say, without any reservation, they are not worth it. Not worth it for the small projects nor the large projects. They significantly complicate the development workflow and add another layer of (often times, cumbersome) abstraction between the user and the data. If you encounter any i…

I've ripped out broken ORM on multiple projects with over-engineered domain models designed by people with no apparent knowledge of how to do a proper database design. This is the key problem with ORM. It leads to lots of unnecessary joins just so you can pretend databases do inheritance or all those tiny objects you will never query on need dedicated tables with indexed columns. It's stupid. It's also stupidly slow,…

> ORMs don't have to be a problem but they nudge people into doing very sub optimal things.

I don't think good ORMs do any nudging. The issue arises when people assume that because they are using an ORM they don't have to learn the underlying DB. ORMs should be treated as tools that sit on top of your SQL knowledge and allow you to do certain types of things easier.

Like any tool, there are inappropriate uses cases. On one side you have people using an ORM to implement a document store, on the other side you have people that end up hand-rolling a crappy ORM because they thought they didn't need one.

Re: What ORMs have taught me: just learn SQL (2014)

#413

This was my position for a while. ORMs introduce a layer of magic which obscures what's actually going on under the hood. I decided I would just make raw SQL queries and handle mapping data explicitly. I quickly ended up with a lot of duplicated code. So then I thought, "Well ok, I should add a bit of abstraction on top of this..." I started coding some simple functions to help map the tabular data to objects. One th…

Sometimes you just should live with duplicated code. It's OK.

The best of both worlds is write your own universal preprocessor...

Re: What ORMs have taught me: just learn SQL (2014)

#414
post #255

Earlier quoted context omitted.

Ya I’ve heard this one a lot. It’s kind of funny to say and does humorously underline the complexity of the problem but people take it seriously. So to take it seriously for a second: There was no good reason to be in Vietnam; even taking the stated rationale as a given, which many people did not, it was a concern many levels removed from the actual safety or functioning of American society. ORMs in contrast achieve…

Tbh you could easily claim that the explicit goal, mapping to objects, is incorrect. The real value is to reduce the damage of the SQL language itself — the unnecessarily ordered clauses, the arbitrary inconsistencies in syntax, the worthless parser errors, the lack of any static typechecking — which cause so much code bloat and debug headaches. There are two reasons to use the ORM: to not learn SQL, and to generate…

> What we really need is a less shitty version of SQL.

Any of the D (Date and Darwen's, not Digital Mars’s) family of relational languages might fit the bill.

Re: What ORMs have taught me: just learn SQL (2014)

#416
post #389
post #333

Earlier quoted context omitted.

> Nobody should be writing raw SQL. What?!? That’s an absolutely foolish and naive assertion. Please don’t give any of your fellow junior devs that “advice”...

Are you advocating that I put a bunch of magic strings in my codebase? That would be a maintenance nightmare. Unless you think I'm suggesting that no devs should ever write SQL at all in their career? Which isn't the case.

> Are you advocating that I put a bunch of magic strings in my codebase? That would be a maintenance nightmare.

Not a bunch, just the large batch queries and reports that use complicated joins. There a places where it makes sense to take the trade-off between maintainability and performance.

> Unless you think I'm suggesting that no devs should ever write SQL at all in their career? Which isn't the case.

It sure appears to be what you are suggesting. Perhaps you should clarify what you were trying to say?

Re: What ORMs have taught me: just learn SQL (2014)

#417
ORMs often implement only the lowest common denominator of all supported databases. Easy changing databases is in a free software world seldom a necessary requirement. If you use a advanced feature rich database often a lot of it is not supported by the ORM.

Re: What ORMs have taught me: just learn SQL (2014)

#418
I have fought with orms for many, many years. I think if you sit behind someone and watch them build an application with an ORM, and you sit behind the same person and watch them use SQL and data access functions and other boring things, the person using the ORM will spend many, many hours fighting to get the ORM to do what they want, or fixing bugs that pop up because the ORM didn't do what they thought it was going to do in subtle ways.

Generally, with threadlocal sessions and an application passing orm data class instances around the code freely (which is by far the most common pattern of use), the application will end up doing 10,000x more queries than the programmer would have guessed (this is a literal number and not an exaggeration). Trying to tell the ORM to preload the tree of objects that is going to be accessed is nearly impossible, since the instances go up and down the stack from function to function, each potentially accessing an attribute of an instance loaded as an attribute of an instance many levels back to the original object intentionally pulled from the database.

ORMs make writing the application 90% faster for the first 2 weeks and then 50% slower from then on.

That doesn't mean you are stuck writing straight SQL queries and passing around rows of data, you can sit for a bit and build data access functions that make your life easier and write classes that represent entities from the data, but without your data going through tens of thousands of lines of (extremely well engineered and thoughtful) ORM code that you have no hope of ever understanding well enough that you will avoid catastrophic mistakes that are extremely hard to fix.

And you will make catastrophic mistakes, mistakes you would probably never make with SQL. SqlAlchemy has 5 states that orm objects can be in. If you are using SqlAlchemy and you can't instantly tell me what those 5 states are, and the detailed description of each, you are already making huge mistakes and corrupting data.

To quote one section from the many pages of SQLAlchemy documentation about 'session state management' (and if you don't know all this stuff by heart you will end up learning a lot of it the hard way):

==============================================

The SELECT statement that’s emitted when an object marked with expire() or loaded with refresh() varies based on several factors, including:

The load of expired attributes is triggered from column-mapped attributes only. While any kind of attribute can be marked as expired, including a relationship() - mapped attribute, accessing an expired relationship() attribute will emit a load only for that attribute, using standard relationship-oriented lazy loading. Column-oriented attributes, even if expired, will not load as part of this operation, and instead will load when any column-oriented attribute is accessed.

relationship()- mapped attributes will not load in response to expired column-based attributes being accessed.

Regarding relationships, refresh() is more restrictive than expire() with regards to attributes that aren’t column-mapped. Calling refresh() and passing a list of names that only includes relationship-mapped attributes will actually raise an error. In any case, non-eager-loading relationship() attributes will not be included in any refresh operation.

relationship() attributes configured as “eager loading” via the lazy parameter will load in the case of refresh(), if either no attribute names are specified, or if their names are included in the list of attributes to be refreshed.

Attributes that are configured as deferred() will not normally load, during either the expired-attribute load or during a refresh. An unloaded attribute that’s deferred() instead loads on its own when directly accessed, or if part of a “group” of deferred attributes where an unloaded attribute in that group is accessed.

For expired attributes that are loaded on access, a joined-inheritance table mapping will emit a SELECT that typically only includes those tables for which unloaded attributes are present. The action here is sophisticated enough to load only the parent or child table, for example, if the subset of columns that were originally expired encompass only one or the other of those tables.

When refresh() is used on a joined-inheritance table mapping, the SELECT emitted will resemble that of when Session.query() is used on the target object’s class. This is typically all those tables that are set up as part of the mapping.

=========================================

Yep, sounds like an ORM makes life a lot simpler!

Re: What ORMs have taught me: just learn SQL (2014)

#419

Earlier quoted context omitted.

Sorry, maybe I wasn't being clear. I don't just validate that the request is JSON, I validate that the fields in the JSON are valid fields to send over the wire. I do this by automatically hooking my ORM models into my request validation. If a request doesn't specify a column that is NOT-NULL, for example, it will automatically send an error response telling the client that it needs to specify that column in the requ…

Python doesn't have type safety to begin so those sort of checks have less utility to me and since json.loads returns a dictionary and python objects are effectively dictionaries you are pretty much done.

> Python doesn't have type safety

It does, if you want it to, with several typecheckers available.

Post reply on HN