Electron100 / butane

An ORM for Rust with a focus on simplicity and on writing Rust, not SQL
Apache License 2.0
93 stars 13 forks source link

How to do join? #12

Open alianse777 opened 3 years ago

alianse777 commented 3 years ago

Is there any way to join tables by field(s)? Like join!(query!(Users, id == {id}), query!(Posts, date == {date}), Users.id == Posts.user_id) which returns a tuple (Users, Posts)?

Electron100 commented 3 years ago

Hi @alianse777, sorry for the slow reply -- it's been a busy week. Butane doesn't expose a join operation per se, in part because it's deliberately object-oriented, although I'm not necessarily opposed to such a feature in the future. It would be more idiomatic for Post to have a user: ForeignKey<User> field than a user_id: i64 one. The User can be retrieved from the Post by calling load on the ForeignKey. The obvious downside of this approach is that each load is a separate roundtrip to the database. I do have planned work to support prefetching the referents of certain foreign keys in the original query, much as Django does, but that's not implemented yet.

If you let me know exactly what you're hoping to do with a list of users and posts I may be able to suggest something more concerete.

alianse777 commented 3 years ago

Maybe add query!(...).load_with_foreign_keys() method to retrieve (non-recursively) all objects at once and return a tuple or make ForeignKey a enum with Loaded and Unloaded variant?

Electron100 commented 3 years ago

Yes, something like load_with_foreign_keys is what I'm planning to add. I'll see if I can get to it in the next couple weeks.

ForeignKey already supports a loaded vs unloaded state via an internal OnceCell, so the second part isn't an issue.