How do I get an object from a relationship by object's PK?

117 views
Skip to first unread message

Sergey V.

unread,
Aug 21, 2012, 5:47:18 PM8/21/12
to sqlal...@googlegroups.com
Hi all,


Basically, I'm looking for a dict-like access to a relationship to be able to quickly retrieve items by some key (item's PK). To illustrate, a "normal" relationship is list-like:

    for book in library.books:
        print book.id  # prints 10, 20, 30

In addition, I'd like to be able to access "books" from an already-loaded relationship by their id:

    book1 = library.books.by_id(10)
    book2 = library.books.by_id(20)
    book3 = library.books.by_id(23)  # raises KeyError

while still being able to iterate over library.books in a list-like manner.

I'm looking at MappedCollection (http://docs.sqlalchemy.org/en/latest/orm/collections.html?highlight=collection#custom-dictionary-based-collections) - would building a custom collection class be the right solution to the problem? Or is there something pre-built for this purpose in the depths of SQLAlchemy?

Thanks,

Michael Bayer

unread,
Aug 21, 2012, 11:33:38 PM8/21/12
to sqlal...@googlegroups.com
there's two variations here.   One, which is definitely the quickest, is just to use a @property that re-evaulates library.books as a dict:

@property
def books_by_id(self):
    return dict((book.id, book) for book in self.books)

the other, the more "integrated" approach, is to use a collection_class that's mostly a dict but just yields the values instead of the keys when iterated.   It might be nice if attribute_mapped_collection provided a simple argument to pass in a "dict" subclass but apparently it doesn't have this yet, so just subclass MappedCollection:

class IterateValuesDict(MappedCollection):
    def __iter__(self):
        return iter(self.values())

collection_cls = lambda: IterateValuesDict(keyfunc=lambda obj: obj.id)

class Library(Base):
    # ...
    books = relationship(Book, collection_cls=collection_cls)





Thanks,

--
You received this message because you are subscribed to the Google Groups "sqlalchemy" group.
To view this discussion on the web visit https://groups.google.com/d/msg/sqlalchemy/-/mUIFlVguh34J.
To post to this group, send email to sqlal...@googlegroups.com.
To unsubscribe from this group, send email to sqlalchemy+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.

Reply all
Reply to author
Forward
0 new messages