Anvil ORM Library

Building on the really rather fantastic New: Portable Classes, here’s a library I’m working on to provide an Object Relational Mapper (ORM) for anvil:

Using this library, you can write simple classes such as:

@model_type
class Person:
    first_name = Attribute()
    last_name = Attribute()

and then use that class to create new Person instances, save them to a data table,
fetch them back and update them with code as simple as:

from .model import Person

person = Person(first_name="Owen").save()

person.last_name = "Campbell"
person.save()

people = Person.search()

And you can do that in both client and server side code!

It’s working nicely but the documentation is somewhat lacking at the moment!

9 Likes

Does the paging mechanic work with data grids?

I am unfortunately too far along in my current project to rewrite it to use this, but am looking forward to using it on my next project.

Yes, it does. That’s what led me to write it!

2 Likes

This looks amazing - and having come from a Django background, reassuringly familiar :wink:

2 Likes

Thank you kindly! It is indeed heavily influenced by both Django and the attrs library.

(And I’ve just noticed that was your first post here. I feel honoured! Thank you again).

1 Like

I would really love to see this become part of the Anvil standard library. I think it would really help beginners like me, if only we can first understand what it is. Unfortunately, I had no previous familiarity with the ORM concept so I had difficulty wrapping my head around this initially. I found the tutorial really helpful, though. Maybe I’ll submit some pull requests to your documentation as I develop a better grasp of the details.

1 Like

Kind words. Thank you!

Unfortunately, I haven’t had time to polish the docs and the library actually does far more than is covered in the tutorial - the titles of the howtos are there to remind me what I need to write up!

2 Likes

Working on a simple one-off project, and am trying to integrate the ORM library to get some experience with it. I ran into one issue, and had some questions:

  1. These imports in persistence didn’t work for me based on how the tutorial said to create the folder structure:
from app.server_lib.crud import security
from app.client_lib.crud.particles import 

I had to change them to this:

from . import security
from .lib.crud.particles import ModelSearchResults
  1. It doesn’t seem possible to use get to get a single item using something other than the uid. In my case I have a unique field in the table I want to fetch an item by. I could use search, check the length, and get the first element, but it’d be really nice if there were an equivalent to the Anvil data tables get. Maybe there’s something I’m just not seeing to do that?

  2. Related to #2 above, how would I go about getting just the first item out of a set of search results? The ModelSearchIterator doesn’t respond well to next(results), claiming it’s not an iterator. What I ended up doing is very hacky:

    rooms = Room.search(roomid=self.url_dict['id'])
    
    for room in rooms:
      self.roomname.text = room.name
      break
  1. Is there an order by equivalent for search?

  2. How do you go about searching by linked table rows? I’d assumed it’d be by passing in the full object, but that gives me an invalid query value issue. It was for this model:

@model_type
class Roll:
    room = Relationship(class_name="Room")
    name = Attribute()
    when = Attribute()
    rolls = Attribute()

And this search:

results = Roll.search(room=room)

@jshaffstall

Sorry you had a bit of trouble with the library.

For the first problem, the docs are a little behind the code and it looks like a copy/paste has also crept in. I’ll try to get those fixed shortly.

2 and 3 sound like good ideas which could be added.

4 and 5 aren’t supported and aren’t likely to be.

UPDATE

After some conversation via DM, I utterly failed to read and understand number 5 before answering! That is supported at the moment by a wholly undocumented ‘cross reference’ feature.

I’ve pushed a new release (v0.1.18) with (hopefully) the package structure, imports and docs aligned. I’ll try to carve out some time to work on this library but, unless one of my paying jobs has a need, it’s tricky to find that time at the moment.

2 Likes

The library has now moved into the Anvilistas team:

2 Likes

is anvil-orm the lib used with data_table?

Hi @CSun

It’s a library you can choose to use on top of data tables, if you wish.

1 Like

@owen.campbell
Thanks for this great contribution!
Your ORM lib is a simple yet very effective way to quickly create and manage an app data model.
However, I stuck with issue #5 mentioned by @jshaffstall
I am trying to understand how to use cross-reference for search but would appreciate it if you could give me a hint.

Thank you!

Searching by cross reference isn’t supported. You’ll need to use an app tables search instead.

so, the current version of the ORM library does not support search by Relationship field at all, correct?

That’s correct, yes.