4 ms·
I don’t find the “magic” SQL generation that problematic in practice. The main problem with ORMs is that as a class they are, broadly speaking, all fat model Ac
by fennecfoxen 6y ago
I don’t find the “magic” SQL generation that problematic in practice. The main problem with ORMs is that as a class they are, broadly speaking, all fat model ActiveRecord patterns which encourage you to make the models fatter and to spread invisible dependencies on these models (and their related models and the methods) throughout the codebase. The result is invariably a big ball of mud.
Immutable entities, produced by a set of ORM-like and mostly automatic GetX/PersistX services, is more generally the sound way forward. Unfortunately it’s also far less convenient than most ORMs in practice, as frameworks like Rails prioritize realizing the messier vision.
- greatgib 6y agoA few examples of the magic and the implicit rules that leads to confusion: query(object1).where(object1.prop=10).orderby(prop).join(object2).where(object1.prop=object2.bar) Looks like to be logical blocks that you can easily chain together, but is the order important and can each "subfunction" be used anywere? or after a specific previous one? Probably join couldn't be used after orderby. What is the state before the join, the available tables? Where inside the sql will be applied the where? What object will be available? Some ORM even do kind of "autojoin" on table that it detects based on arguments used in later where clauses.
- tremon 6y agoThe problem with the object-based model is that, by definition, it constrains the developer into patterns that have an impedance mismatch with the underlying database: as a general rule, the objects are either fat models that always pull the entire record from the database, or they're proxy objects that only fetch minimal data first, and then do a round-trip to the database for every subsequent property access. Neither is a good fit for databases, which excel in slicing and dicing your data to retrieve only the exact properties you require, no more, no less. LINQ alleviates this somewhat because it allows anonymous objects, but the fundamental problem is still the same: the SQL (relational) model relies heavily on column filtering and result set composition, neither of which can be abstracted properly with object-oriented programming. And let's not even get started about using the object model to enforce storage invariants, like NOT NULL or FOREIGN KEY validation. These invariants should have little bearing on how the models are treated during runtime, because there are valid reasons for a record to be incomplete (the partial resultset mentioned above, an object still under construction, etc). So, in my view, here's what a good "ORM" should be able to do: - construct and fetch an object using any subset of the model properties, leaving the others empty (preferably explicit) - allow composition of multiple models in both data retrieval and search parameters - have an explicit distinction between storage invariants and business invariants (e.g. a function reporting on aggregate sales should not need to fetch every individual sales line, even though the model says that every sales order requires at least one item line) At which point, you're merely replicating the relational model in your "ORM", and you're better off avoiding the abstraction entirely. That doesn't mean you shouldn't use model definitions that match your database records. But your ORM shouldn't be an abstraction between your models and your database -- it should expose the full relational capabilities to your developers, because they're going to need those capabilities anyway. [ but note, I haven't actually worked with any recent ORM except for esqueleto -- and I'm pretty sure it doesn't qualify as an ORM ]