News for hackers. Stuff that matters.
Re:Ent: An Entity Framework for Go by Fire-Dragon-DoL on Sunday October 30, 2022 @06:59PM (#33399920)
I keep thinking that the query portion should be entirely split from the ORM portion. Query builder have specific usage, but are not the norm. None of them can model an advanced postgres query, but at the same time, they provide little (or nothing) utilities to map the data coming from a complex query, back to objects, which is funny, to me that would be the definition of "object relational mapper".

I know why activerecord does this: it's way easier to do the join in memory, so that one row is obtained per object and not an enormous row representing many, but not providing any utility for raw queries seems a big missing feature.

Edit: to be clear, by query I refer to read operations (select) that are not trivial (find one by id would be trivial)

Re:Ent: An Entity Framework for Go by jitl on Sunday October 30, 2022 @07:59PM (#33400386)
In a typical ORM I agree about the query builder. Most ORMs encourage the typical use of a relational database where SQL fits the domain well.

But Ent is modeling data as a graph, and the DB behind the scenes is more of an implementation detail. The production version of Ent used at Meta stores data in TAO (https://engineering.fb.com/2013/06/25/core-data/tao-the-powe... my impression is that product engineers do not write any SQL when working with Ent at Meta.

Re:Ent: An Entity Framework for Go by Fire-Dragon-DoL on Sunday October 30, 2022 @08:07PM (#33400452)
I might be misreading here, but are you suggesting that the DB behind the scenes is not modeling things in the traditional sense but rather as a graph. Thinking of postgres, this could be by dumping a big json object in a generic "graph" table. Is that the case?

That would be acceptable from my point of view. The problem is using SQL as a graph produces very inefficient queries once hitting a certain scale, but if the DB is already a graph, the problem should be limited.

Re:Ent: An Entity Framework for Go by jitl on Sunday October 30, 2022 @08:18PM (#33400517)
The way TAO (and Notion to some degree) deal with this is by tightly coupling the persisted (SQL?) data store to an in-memory cache that make KV style reads like “get foo by foo_id” extremely fast. They also limit the kinds of queries developers can write to the ones more likely to be very fast on the infrastructure.

Pushing graph queues down to a single SQL query so that the SQL DB spends massive CPU time on joins can be an issue. Instead these systems can avoid talking to the SQL DB at all for example if they’re on the happy path just chasing graph edges.

Re:Ent: An Entity Framework for Go by Fire-Dragon-DoL on Sunday October 30, 2022 @08:28PM (#33400598)
That makes sense. In a certain way, it's doing something similar to react-query
Re:Ent: An Entity Framework for Go by guggle on Monday October 31, 2022 @02:16AM (#33402583)
> the DB behind the scenes is more of an implementation detail

Ugh... what a bummer then.

Re:Ent: An Entity Framework for Go by a8m on Monday October 31, 2022 @02:28AM (#33402632)
Just to emphasize, that OSS version of Ent models SQL tables in the traditional way (edges as foreign-keys and join-tables). i.e., the database structure is not obscure or something and can be easily read by developers and ported to other ORMs in case it's needed.
Re:Ent: An Entity Framework for Go by bokwoon on Sunday October 30, 2022 @09:09PM (#33400861)
> at the same time, they provide little (or nothing) utilities to map the data coming from a complex query, back to objects

Example of a query builder with built-in mapping capabilities (it’s mine):

https://github.com/bokwoon95/sq

I feel some exasperation when I see query builders that throw a query string back to the user and ask them to map the results themselves. That’s easily the most tedious and mistake-prone part of using SQL queries. In the case of my library, projection and mapping are handled by the same callback function so in order to SELECT a field you basically map it and it’s automatically added to the SELECT clause.

Re:Ent: An Entity Framework for Go by Fire-Dragon-DoL on Sunday October 30, 2022 @09:42PM (#33401072)
I skim-read it but couldn't find an example of what I think as challenging: a join of 3 tables (well, even two).

When you join 3 tables (assuming has many and "has many through" relationships), what you get back is enormous rows and multiple rows, all of this in tabular form, but in the software is usually represented as a graph. I'd love a library that helps building back these massive rows into relationships.

Please forgive me if your library does this, while I saw the "mapping function", I didn't see anything to help me build back graphs. I can map rows "easily", but I cannot recreate associations easily, it requires a bunch of work.

Re:Ent: An Entity Framework for Go by bokwoon on Monday October 31, 2022 @12:32PM (#33408221)
> I didn't see anything to help me build back graphs

Hmm you've certainly given me something to think about. Thanks.

BTW joins are not challenging, but you made me realize I didn't show any joins in my basic examples. Here is an UPDATE with JOIN in the meantime: https://bokwoon.neocities.org/sq.html#postgres-update-with-j....

Re:Ent: An Entity Framework for Go by Fire-Dragon-DoL on Tuesday November 01, 2022 @10:34PM (#33430810)
Thank you for the examples. I see the joins example, but they seem to be about creating queries, not mapping data.

    sql = "select blog.name, post.content, author.display_name from blog join post on blog.id = post.blog_id join author on post.author_id = author.id"
Assuming the relationship: many blogs have many posts and posts have one author, I'd expect something along the lines of (sudo code):

    schemaOnTheFly = Blogs{}.HasMany(Posts{}.HasOne(Author{}) // Sorry the syntax for this doesn't really exist
    blogs := query.Exec(sql, params, schemaOnTheFly)

    fmt.Printf("%+v\n", blogs[0].Posts[0].Author)
That's what I'd expect. Do notice that the schema is per-query, I'll let the developer handle the sharing portion of the schema (might be shared by a few queries)
Re:Ent: An Entity Framework for Go by robertlagrant on Monday October 31, 2022 @06:20AM (#33403890)
> I keep thinking that the query portion should be entirely split from the ORM portion

This is how SQLAlchemy does it. Lower level query tier you can use directly, and a higher level ORM tier that uses the query tier.