Differences between ETS and Postgres

So my thinking right now is, I'm using ETS to build out all of my resources and basically the app for as long as I can get away with. I do realize there are some differences between the Postgres adapter and ETS such as when it comes to identities where you've to add pre_check_with. However, are there some major differences where Ash is not able to abstract away the data layer and the code would actually be different for the two? I just wanted to keep open the option of selecting a database later. Maybe PlanetScale (which is MySQL, but doesn't support foreign key constraints and has some other limitations too), or Postgres or SQLite. Of course I understand we'll have to figure out how to create a data layer for those as they don't exist in Ash right now, but maybe I could help with one of those if we decide to go that route?
8 Replies
ZachDaniel
ZachDaniel•3y ago
Help with those other data layers would be great 🙂 I think what we'd basically want to do is do something similar to what ecto did and have an ash_sql and just put all of the main sql implementations into one dependency. Anyway, as for your real question: yes there are differences, and they mostly come into play when it comes to working with filters or calculations where you might want to use fragment For example, if there is no operator in ash for something you can do
calculate :foo, :string, expr(fragment("? ^&* ?", foo, bar))
calculate :foo, :string, expr(fragment("? ^&* ?", foo, bar))
with postgres (the made up ^&* operator is just an example of some random sql you can embed)
Arjun Bajaj
Arjun BajajOP•3y ago
that's fair. since its SQL I cannot expect it to work in ETS. So apart from that, Ash should most abstract away everything else.
ZachDaniel
ZachDaniel•3y ago
Yep, for all the main pieces we aim to either abstract it away or make you do something about it (like the identity checking) We also support cross data layer operations (with the exception of aggregates and calculations on a sql resource touching things on an ets resource, there is no reasonable way to do that in real life) But you can do things like this:
Ash.Query.filter(exists(some_postgres_relationship, id == ^foo))
Ash.Query.filter(exists(some_postgres_relationship, id == ^foo))
and Ash will "synthesize" it can't guarantee full support, but usually enough to get through your prototyping phase
Arjun Bajaj
Arjun BajajOP•3y ago
As an aside, after watching your video on LiveView Mastery where you implement the Twitter clone, and listening to the Thinking Elixir, I was impressed by how Ash does queries in the most performant way possible. So I cloned the ash_postgres repo to see how big it is, and well, tokei shows there are almost 11k lines of code in the lib folder! My thinking to create a data layer for let's say PlanetScale was, we could clone it, make the necessary changes to connect it to MySQL, and then figure out all the code changes required until the tests pass. But if the ash_sql abstraction is possible, I'm sure that's a better route.
ZachDaniel
ZachDaniel•3y ago
It wouldn't hurt to clone it, find out how different it is and then abstract the commonalities into another repo Might be a good exercise in discovery to just see how much needs to change without worrying about the abstraction part at the outset
Arjun Bajaj
Arjun BajajOP•3y ago
That's a great idea, I can maybe try that as an experiment after a few weeks or something. I don't understand nearly enough of Ash to attempt it right now though. Like I haven't even ventured into aggregates and a bunch of other features! I'll keep you updated if I try it out. That's another interesting thing I found about Ash. PlanetScale doesn't support foreign key constraints and has other limitations as they say it would not be possible to build their scalable architecture otherwise. However, I would be wary of not using FKs in production simply because I would be afraid of making an error in my code. But using Ash, since it abstracts away the data layer almost completely, I think a combination of the two would work surprisingly well for many applications.
ZachDaniel
ZachDaniel•3y ago
Yeah, because we have tools to at least help you do as well as you can with a setup like that (like eager/pre/post checking identities and things like manage_relationship which will lookup/match records before relating them) It might mean its slightly slower on individual operations, but safer and more performant at scale in general
Arjun Bajaj
Arjun BajajOP•3y ago
Thanks for all your help again!

Did you find this page helpful?