5 ms·
I suppose the Go philosophy would discourage developers from tightly coupling Go types and their relational representations through an ORM. The idiomatic way of
by sagichmal 13y ago
I suppose the Go philosophy would discourage developers from tightly coupling Go types and their relational representations through an ORM. The idiomatic way of mapping your objects to a database is by defining a thin interface around a sql.DB, with first-class operations for your concrete types.
type User struct {
ID int
Permalink string
}
type Storage sql.DB
Then you can either do
func (s *Storage) WriteUser(user User) error {
if _, err := s.Exec(
"REPLACE INTO users VALUES (?, ?)",
user.ID,
user.Permalink,
); err != nil {
return fmt.Errorf("write user failed: %s", err)
}
return nil
}
or
func (u User) Write(storage Storage) error {
if _, err := storage.Exec(
"REPLACE INTO users VALUES (?, ?)",
u.ID,
u.Permalink,
); err != nil {
return fmt.Errorf("write user failed: %s", err)
}
return nil
}
It's a bit more laborious in the sense of keystrokes, but it's also more explicit, which is, on balance and over the lifetime of a large software project, a good thing.
- gnaritas 13y agoYuk, that's just manually doing what ORMs give you automatically; that's not a good thing, you're being a human compiler.
- sagichmal 13y ago> you're being a human compiler. The transformation from "type instance in my language" to "relational data in my storage engine" is absolutely not "compilation". It's a subtle translation of data and grammar, and as the type relationships grow more complex, ORMs fail. The lesson of ActiveRecord, from the perspective of Go, is that ORMs are fundamentally broken abstractions.
- gnaritas 13y agoDon't be pedantic, my point was clear and you obviously understood it. As for the lessons of active record, says who?
- chc 13y agoWell, Martin Fowler has gone on the record saying that Active Record (the design pattern, of which Ruby's ActiveRecord is one implementation) is not well-suited to sophisticated data models, and he tends to prefer the Data Mapper pattern — which similar to what's being described for Go.
- camus2 13y agoexpect it is quite hard to write a generic data mapper in go as well. something like Hibernate or Doctrine ORM would be nearly impossible to write with go.i'm not talking about the basic features but advanced features of both frameworks.
- chc 13y agoThat is true, but genericity is actually not an inherent attribute of Data Mapper. The key idea is that there are fundamental incompatibilities between two data models (e.g. a structure in your program and a relation in your database), and the translation between the two models is a reified component of the program rather than just being absorbed into the behavior of the object itself as in Active Record. There are some efforts along these lines, such as gorp (https://github.com/coopernurse/gorp https://github.com/coopernurse/gorp), but I don't think they're all that widely used.
- gnaritas 13y agoThat's not what the OP said, he said the lesson was "that ORMs are fundamentally broken abstractions". Fowler does not believe this, and even if he did, his opinion is certainly not a global lesson as if it were now best practice to consider ORMs fundamentally broken.
- Jweb_Guru 13y agoI do, for one, but don't take my word for it... lots of very intelligent people have problems with ORMs. http://blogs.tedneward.com/2006/06/26/The+Vietnam+Of+Computer+Science.aspx http://blogs.tedneward.com/2006/06/26/The+Vietnam+Of+Compute... presents a good summary of the problems involved (forgive the inflammatory title). Despite its many problems, SQL remains the best way of interacting with a relational database.
- camus2 13y agothat's not the issue here, wether a pattern is good or not is irrelevant.The question is ,is it possible to write something like ActiveRecord and keep its most advanced features in Go. Right now the lack of genericity in the language makes it a no go.
- kohanz 13y agoThank you for the detailed answer. It's a bit more laborious in the sense of keystrokes, but it's also more explicit, which is, on balance and over the lifetime of a large software project, a good thing. OTOH, it feels like a high development cost to pay, relative to the alternatives out there. You certainly wouldn't use it for an MVP. Also, it would increase the opportunities to introduce bugs into the application (unless one actually feels they can write something better than, say ActiveRecord, from scratch). I have a side-project in RoR that would benefit greatly from the performance boost provided by Go. However, the idea of writing all of the ORM functionality that ActiveRecord handles for me (not just managing of objects as you've shown, but the relationships between them) is quite daunting.
- sagichmal 13y ago> (unless one actually feels they can write something > better than, say ActiveRecord, from scratch). The point is that ActiveRecord's method of modeling, especially when it comes to dynamically mapping language constructs to a storage layer via SQL, is too implicit. Too costly. Actively harmful! The point is to get developers to stop thinking in terms of ORM abstractions, and start thinking in terms of the actual transforms and manipulations that are occurring. > You certainly wouldn't use it for an MVP. I think you overestimate the cost of pressing buttons on your keyboard.
- kohanz 13y agoThe point is to get developers to stop thinking in terms of ORM abstractions, and start thinking in terms of the actual transforms and manipulations that are occurring. Isn't the point also to encourage code re-use and abstraction? I mean, golang has packages for a reason. I suppose my question is more along the lines of whether we'll ever see a package in go that would standardize the data-object divide or whether this will always be a "roll your own" domain? I think you overestimate the cost of pressing buttons on your keyboard. Then why don't we "roll your own" for everything?
- sagichmal 13y ago