Thanks, it worked. If someone is interested: class UrlBundle(Bundle): def __init__(self, *args, suffix='', **kwargs): super().__init__(*args, **kwargs) self._suffix = suffix
def create_row_processor(self, query, procs, labels): s_proc = super().create_row_processor(query, procs, labels) suffix = self._suffix def proc(row, a): entity = s_proc(row, a) return get_url(entity.id, entity.file_name, entity.storage_type, suffix) return proc class File(Base): id = Column(Integer, primary_key=True) file_name = Column(Unicode(255)) storage_type = Column(EnumInt(STORAGE_TYPE)) @hybrid_method def get_url(self, suffix=''): return get_url(self.id, self.file_name, self.storage_type, suffix) @get_url.expression def get_url(cls, suffix=''): return UrlBundle('url', cls.id, cls.file_name, cls.storage_type, suffix=suffix) And now I can do queries such as: session.query(File.get_url('150x150')).filter_by(id=123) On Tuesday, September 22, 2015 at 4:33:51 PM UTC+3, Michael Bayer wrote: > > > > On 9/22/15 7:18 AM, Yegor Roganov wrote: > > I know that I can encapsulate multiple columns into one using either > composite column or hybrid_property, but unfortunatelly neither suits me > 100%. > > Let's say I have a `File` model which includes fields `id`, 'file_name`, > `storage_type`, > and there is a `get_url` python function that when given `id`, 'file_name` > and `storage_type` returns the constructed url. > > I want know to have a computed property `url` on the `File` model and be > able to make queries such as > ``` > f = session.query(File.url).filter_by(id=1).first() > f[0] # should be a url returned by `get_url(f.id, f.file_name, > f.storage_type)` > ``` > > I obviously cannot use `hybrid_property` since it only allows sql (which > is expected). > What comes very close is `sqlalchemy.orm.composite`. > I can define composite class such as: > ``` > class UrlComposite: > def __init__(self, id, file_name, storage_type): > self.id = id > self.file_name = file_name > self.storage_type = storage_type > > def __composite_values__(self): > return self.id, self.file_name, self.storage_type > > def __eq__(self, other): > return self.id == other.id and self.file_name == other.file_name\ > and self.storage_type == other.storage_type > > def __ne__(self, other): > return not self.__eq__(other) > > def get(self'): > return get_url(self.id, self.file_name, self.storage_type) > ``` > Then I can do: > ``` > f = session.query(File.url).filter_by(id=1).first() > f[0].get() # extra get! > ``` > it's almost what I wanted, but know to obtain the url I need to call a > getter method on `UrlComposite`, which ideally I'd like to avoid. Is this > possible? > > probably a Bundle can do this, since you can write your own > create_row_processor method to return whatever you want, see > http://docs.sqlalchemy.org/en/rel_1_0/orm/loading_columns.html?highlight=bundle#column-bundles > > > > I hope my question is clear, thanks in advance! > -- > You received this message because you are subscribed to the Google Groups > "sqlalchemy" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to sqlalchemy+...@googlegroups.com <javascript:>. > To post to this group, send email to sqlal...@googlegroups.com > <javascript:>. > Visit this group at http://groups.google.com/group/sqlalchemy. > For more options, visit https://groups.google.com/d/optout. > > > -- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+unsubscr...@googlegroups.com. To post to this group, send email to sqlalchemy@googlegroups.com. Visit this group at http://groups.google.com/group/sqlalchemy. For more options, visit https://groups.google.com/d/optout.