[sqlalchemy] Re: Extended Query subclass with add_named_column method
wouldn't this be accomplished more simply using contains_eager() ? On Mar 31, 2009, at 9:12 AM, Bob Farrell wrote: Hello, SQLAlchemy people, So I spoke to jek on IRC to see if there was a way to use add_column without causing the query to return a RowTuple and it doesn't look like there is, so I wrote this: class AdditiveQuery(Query): Extended sqlalchemy.orm.Query class with add_named_column method to add a column onto a query but store the values on the main RowProxy object instead of yielding RowTuples as add_column does: q = AdditiveQuery(FooModel, session=some_session) q = q.join((BarModel, FooModel.x == BarModel.x)) q = q.add_named_column(BarModel.baz, 'bar_baz') for row in q: print q.bar_baz def __init__(self, *args, **kwargs): self._named_columns = [] super(AdditiveQuery, self).__init__(*args, **kwargs) def add_named_column(self, column, alias=None): if alias is None: alias = column.key if alias in self._named_columns: raise ValueError(Alias %s already in use. % (alias,)) self._named_columns.append(alias) return self.add_column(column) def __iter__(self): def g(it): checked = False for rows in it: row = rows[0] rest = rows[1:] for alias, value in zip(self._named_columns, rest): if not checked and hasattr(row, alias): raise ValueError(Alias %s already exists on original row object. % (alias,)) setattr(row, alias, value) yield row checked = True it = super(AdditiveQuery, self).__iter__() return g(it) The only immediate issue I can think of with this is that if you do AdditiveQuery(FooModel, BarModel) then this is going to blow up as it'll try to call setattr on a RowTuple - I'm not sure whether to a) just let this happen, b) take preventative measures and raise a more useful exception, c) allow specifying exactly which entity to attach the named_column onto. Any suggestions welcome and, of course, if any of the SA boys want to stick this into SQLAlchemy, you're more than welcome. Thanks ! --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: Extended Query subclass with add_named_column method
Yes, if this has been defined on the mapper. Generally I do a lot of just using SQLAlchemy to as a way of writing SQL in Python code that can be passed around for dynamically building up queries so my mappers tend to be quite bare - or are you suggesting this can be done without configuring the relation on the mapper ? If there's a way to do this in SQLAlchemy that doesn't need extra mapper config then I'm all ears. :-) On Mar 31, 3:22 pm, Michael Bayer mike...@zzzcomputing.com wrote: wouldn't this be accomplished more simply using contains_eager() ? On Mar 31, 2009, at 9:12 AM, Bob Farrell wrote: Hello, SQLAlchemy people, So I spoke to jek on IRC to see if there was a way to use add_column without causing the query to return a RowTuple and it doesn't look like there is, so I wrote this: class AdditiveQuery(Query): Extended sqlalchemy.orm.Query class with add_named_column method to add a column onto a query but store the values on the main RowProxy object instead of yielding RowTuples as add_column does: q = AdditiveQuery(FooModel, session=some_session) q = q.join((BarModel, FooModel.x == BarModel.x)) q = q.add_named_column(BarModel.baz, 'bar_baz') for row in q: print q.bar_baz def __init__(self, *args, **kwargs): self._named_columns = [] super(AdditiveQuery, self).__init__(*args, **kwargs) def add_named_column(self, column, alias=None): if alias is None: alias = column.key if alias in self._named_columns: raise ValueError(Alias %s already in use. % (alias,)) self._named_columns.append(alias) return self.add_column(column) def __iter__(self): def g(it): checked = False for rows in it: row = rows[0] rest = rows[1:] for alias, value in zip(self._named_columns, rest): if not checked and hasattr(row, alias): raise ValueError(Alias %s already exists on original row object. % (alias,)) setattr(row, alias, value) yield row checked = True it = super(AdditiveQuery, self).__iter__() return g(it) The only immediate issue I can think of with this is that if you do AdditiveQuery(FooModel, BarModel) then this is going to blow up as it'll try to call setattr on a RowTuple - I'm not sure whether to a) just let this happen, b) take preventative measures and raise a more useful exception, c) allow specifying exactly which entity to attach the named_column onto. Any suggestions welcome and, of course, if any of the SA boys want to stick this into SQLAlchemy, you're more than welcome. Thanks ! --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---
[sqlalchemy] Re: Extended Query subclass with add_named_column method
no, you'd need the mapping to be set up.So yes, if you need to compose your result objects together in some way that is specific to your use case and has no relationship to your mappings or any standard SQLAlchemy feature, you need to either post-process the result of Query or create a subclass that does what you want. On Mar 31, 2009, at 9:41 AM, Bob Farrell wrote: Yes, if this has been defined on the mapper. Generally I do a lot of just using SQLAlchemy to as a way of writing SQL in Python code that can be passed around for dynamically building up queries so my mappers tend to be quite bare - or are you suggesting this can be done without configuring the relation on the mapper ? If there's a way to do this in SQLAlchemy that doesn't need extra mapper config then I'm all ears. :-) On Mar 31, 3:22 pm, Michael Bayer mike...@zzzcomputing.com wrote: wouldn't this be accomplished more simply using contains_eager() ? On Mar 31, 2009, at 9:12 AM, Bob Farrell wrote: Hello, SQLAlchemy people, So I spoke to jek on IRC to see if there was a way to use add_column without causing the query to return a RowTuple and it doesn't look like there is, so I wrote this: class AdditiveQuery(Query): Extended sqlalchemy.orm.Query class with add_named_column method to add a column onto a query but store the values on the main RowProxy object instead of yielding RowTuples as add_column does: q = AdditiveQuery(FooModel, session=some_session) q = q.join((BarModel, FooModel.x == BarModel.x)) q = q.add_named_column(BarModel.baz, 'bar_baz') for row in q: print q.bar_baz def __init__(self, *args, **kwargs): self._named_columns = [] super(AdditiveQuery, self).__init__(*args, **kwargs) def add_named_column(self, column, alias=None): if alias is None: alias = column.key if alias in self._named_columns: raise ValueError(Alias %s already in use. % (alias,)) self._named_columns.append(alias) return self.add_column(column) def __iter__(self): def g(it): checked = False for rows in it: row = rows[0] rest = rows[1:] for alias, value in zip(self._named_columns, rest): if not checked and hasattr(row, alias): raise ValueError(Alias %s already exists on original row object. % (alias,)) setattr(row, alias, value) yield row checked = True it = super(AdditiveQuery, self).__iter__() return g(it) The only immediate issue I can think of with this is that if you do AdditiveQuery(FooModel, BarModel) then this is going to blow up as it'll try to call setattr on a RowTuple - I'm not sure whether to a) just let this happen, b) take preventative measures and raise a more useful exception, c) allow specifying exactly which entity to attach the named_column onto. Any suggestions welcome and, of course, if any of the SA boys want to stick this into SQLAlchemy, you're more than welcome. Thanks ! --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~--~~~~--~~--~--~---