[sqlalchemy] Re: column_property for correlated subquery

2013-03-18 Thread millerdev

Forgot to add, I'm on SA 0.7.8

-- 
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?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.




[sqlalchemy] Re: column_property for correlated subquery

2013-03-18 Thread alonn
If I understand the problem correctly your best shot would be using 
sqlalchemy magical `hybrid_property` , hybrid_method, etc.

here:

http://docs.sqlalchemy.org/ru/latest/orm/extensions/hybrid.html



On Monday, March 18, 2013 9:20:15 PM UTC+2, millerdev wrote:

 Hi,

 Using declarative here, and I'm trying to create a column_property with a 
 correlated subquery that returns a count of records with a matching value 
 in some other column. Here's what I've tried. Option 1 is the best, option 
 2 is ugly but second best, option 3 is not a good option since there are 
 many other classes involved and the place where I'd need to put that code 
 is far away from where it logically belongs.

 from sqlalchemy import *
 from sqlalchemy.orm import *
 from sqlalchemy.ext.declarative import *
 from sqlalchemy.ext.declarative import declared_attr

 Base = declarative_base()
 option = 1

 class Foo(Base):
 __tablename__ = 'foo'
 id = Column(Integer, primary_key=True)
 bar_id = Column(Integer, ForeignKey(bar.id))
 name = Column(String)

 if option == 1:
 # does not work (see first traceback below)
 @declared_attr
 def name_count(cls):
 clx = aliased(cls)
 return column_property(
 select(func.count([clx.id]))
 .where(clx.name == cls.name)
 .correlate(cls.__table__))

 if option == 2:
 # does not work (see second traceback below)
 _foo = aliased(Foo)
 Foo.name_count = column_property(
 select([func.count(_foo.id)])
 .where(_foo.name == Foo.name)
 .correlate(Foo.__table__))


 class Bar(Base):
 __tablename__ = 'bar'
 id = Column(Integer, primary_key=True)
 name = Column(String)


 if option == 3:
 # works, but really not where I want to put this code
 _foo = aliased(Foo)
 Foo.name_count = column_property(
 select([func.count(_foo.id)])
 .where(_foo.name == Foo.name)
 .correlate(Foo.__table__))


 Option 1 traceback:

 Traceback (most recent call last):
   File temp/example.py, line 8, in module
 class Foo(Base):
   File .../python2.7/site-packages/sqlalchemy/ext/declarative.py, line 
 1348, in __init__
 _as_declarative(cls, classname, cls.__dict__)
   File .../python2.7/site-packages/sqlalchemy/ext/declarative.py, line 
 1181, in _as_declarative
 value = getattr(cls, k)
   File .../python2.7/site-packages/sqlalchemy/ext/declarative.py, line 
 1554, in __get__
 return desc.fget(cls)
   File temp/example.py, line 15, in name_count
 clx = aliased(cls)
   File .../python2.7/site-packages/sqlalchemy/orm/util.py, line 385, in 
 aliased
 return AliasedClass(element, alias=alias, name=name, 
 adapt_on_names=adapt_on_names)
   File .../python2.7/site-packages/sqlalchemy/orm/util.py, line 298, in 
 __init__
 self.__mapper = _class_to_mapper(cls)
   File .../python2.7/site-packages/sqlalchemy/orm/util.py, line 673, in 
 _class_to_mapper
 raise exc.UnmappedClassError(class_or_mapper)
 sqlalchemy.orm.exc.UnmappedClassError: Class '__main__.Foo' is not mapped


 Option 2 traceback:

 Traceback (most recent call last):
   File temp/example.py, line 16, in module
 select([func.count(_foo.id)])
   File .../python2.7/site-packages/sqlalchemy/sql/expression.py, line 
 1229, in __call__
 return func(*c, **o)
   File .../python2.7/site-packages/sqlalchemy/sql/functions.py, line 16, 
 in __call__
 args = [_literal_as_binds(c) for c in args]
   File .../python2.7/site-packages/sqlalchemy/sql/expression.py, line 
 1440, in _literal_as_binds
 return element.__clause_element__()
   File .../python2.7/site-packages/sqlalchemy/orm/attributes.py, line 
 117, in __clause_element__
 return self.comparator.__clause_element__()
   File .../python2.7/site-packages/sqlalchemy/util/langhelpers.py, line 
 506, in oneshot
 result = self.fget(obj, *args, **kw)
   File .../python2.7/site-packages/sqlalchemy/orm/properties.py, line 
 156, in __clause_element__
 return self.adapter(self.prop.columns[0])
   File .../python2.7/site-packages/sqlalchemy/orm/util.py, line 334, in 
 __adapt_element
 return self.__adapter.traverse(elem).\
   File .../python2.7/site-packages/sqlalchemy/sql/visitors.py, line 185, 
 in traverse
 return replacement_traverse(obj, self.__traverse_options__, replace)
   File .../python2.7/site-packages/sqlalchemy/sql/visitors.py, line 281, 
 in replacement_traverse
 obj = clone(obj, **opts)
   File .../python2.7/site-packages/sqlalchemy/sql/visitors.py, line 270, 
 in clone
 newelem = replace(elem)
   File .../python2.7/site-packages/sqlalchemy/sql/visitors.py, line 182, 
 in replace
 e = v.replace(elem)
   File .../python2.7/site-packages/sqlalchemy/sql/util.py, line 720, in 
 replace
 return self._corresponding_column(col, True)
   File .../python2.7/site-packages/sqlalchemy/sql/util.py, line 695, in