In addition to Athena 0.22.0 | Now with real-time updates!, I have another surprise I’m excited to share. After years of on and off again work, the Athena ORM is now in a state that is functional/usable enough to start gathering feedback. The demo.cr file on the develop branch serves as a good example of what its usage looks like in practice.
Unlike other ORMs in Crystal land at the moment, it has a few unique qualities:
- No custom DSL, entities (models) are normal Crystal classes the use annotations on properties to apply DB related metadata (columns, relationships, PKs, etc).
- Data-Mapper instead of ActiveRecord, a separate service is used to manage entities; e.g. persisting, querying, etc.
- This has some benefits like smarter queries, query batching, and powerful change detection. E.g. when updating an entity only changed values are included in the
UPDATEquery.
- This has some benefits like smarter queries, query batching, and powerful change detection. E.g. when updating an entity only changed values are included in the
- Built-in native relationships/lazy loading, relationships are handled essentially as a
Array(T)whose contents are not loaded until the collection is interacted with. - Repository pattern, simple/one-off queries can handled via basic
find,find_all,find_by,find_one_bymethods, while more complex/reusable/specialized queries can be abstracted to a Repository type that provides better type safety/documentation.
However, as I mentioned, this is still in an Alpha state, so nothing is really set in stone. There are a few things on my near-term list that I am aware of at the moment:
- It’s lacking on the query side of things.
find_byworks enough for simple things, but isn’t really all that type safe nor sufficient to handle more complex queries/joins/etc- Some type of QueryBuilder is on the list, but is of course not small feat
- I do have some ideas on improving type saftey of queries tho, so stay tuned!
NativeQueryis a somewhat verbose but useable escape hatch that can handle more complex/arbitrary SQL- EDIT: It’s also possible access the raw
DB::Connectioninstance to use DB API directly
- How to best use it outside of an Athena context. It’s expected there is a single shared
EntityManagerper-request if in a web context for example. I have some ideas for how to go about this, but want some actual examples of how DBs are used in existing projects, esp those usingDB::Serializableand not an actual ORM before committing - Limited platform/column type support, I have the basics and plan to add more of both in the future
- No testing utilities as of now
- No migration support as of now
- Bugs, there are probably quite a few of them at this point
What I ultimately would like now is for you all to try it for your use cases to identity any bugs, rough edges, our missing features that you run into in the process. Feel free to ping me in this thread, in the Crystal or Athena Discord server to chat more about it!