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.

Reply via email to