you might need to change more than this, but at least the fundamental
thing about @expression is that it has to return a column, not a Query
or a select(). On either one, calling as_scalar() will give you a
scalar subquery, e.g. a SELECT interpreted as a column.
Assuming there's still problems because once array_agg is involved,
things generally get crazy, send along a Wavelength, NSA and MangaNSA
model with that Cube and I can try putting it together.
On 07/29/2016 02:11 PM, Brian Cherinka wrote:
I'm trying to build a hybrid property / expression in one of my SQLA
base classes, and the expression side requires several subqueries and I
cannot for the life of me figure out the correct syntax. I've tried
many different versions / syntaxes for the expression, using the SQL
alchemy expression language, the ORM language but I can't get any of it
work. What am I missing here? Here is my latest attempt.
The setup is this. I have a class called Cube, which is my base object.
For each object in that cube table, I need to grab an attribute from a
table A and use that attribute to modify an array column from a second
table B. And I want to make this new array queryable, thus the
hybridization.
The equivalent raw SQL is
|
select(select(array_agg(unwave.restw))asrestwarr
from(select(unnest(w.wavelength)/(1+n.z))asrestw
frommangadatadb.wavelength asw)asunwave)frommangadatadb.cube asc join
mangasampledb.manga_target asm on m.pk=c.manga_target_pk join
mangasampledb.manga_target_to_nsa ast on t.manga_target_pk=m.pk join
mangasampledb.nsa asn on n.pk=t.nsa_pk join mangadatadb.wavelength asw
on w.pk=c.wavelength_pk limit 5;
|
The instance side is quite easy. The class side is proving difficult.
What is the proper way to write this? I've read through the
documentation countless times now and it hasn't helped much.
|
classCube
@hybrid_property
defrestwave(self):
ifself.target:
redshift =self.target.NSA_objects[0].z
wave =np.array(self.wavelength.wavelength)
restwave =wave/(1+redshift)
returnrestwave
else:
returnNone
@restwave.expression
defrestwave(cls):
session =db.Session()
nsaz =session.query(sampledb.NSA.z.label('z')).\
join(sampledb.MangaTargetToNSA,sampledb.MangaTarget,Cube).\
filter(Cube.mangaid
==cls.mangaid).subquery('nsaz',with_labels=True)
unwave
=session.query((func.unnest(Wavelength.wavelength)/(1+nsaz.c.z)).label('restw')).subquery('unwave',with_labels=True)
restwave =session.query(func.array_agg(unwave.c.restw))
returnrestwave
|
Trying
|
session.query(datadb.Cube.restwave).filter(datadb.Cube.mangaid=='1-113520').all()
|
fails with
|
AttributeError:'Query'objecthas noattribute 'is_clause_element'
|
I've also tried this.
|
@restwave.expression
defrestwave(cls):
unwave
=select([(func.unnest(Wavelength.wavelength)/(1+sampledb.NSA.z)).label('restw')])
restwave
=select([func.array_agg(unwave.c.restw).label('restwarr')]).select_from(
Cube.__table__.join(Wavelength.wavelength).
join(sampledb.MangaTarget).
join(sampledb.MangaTargetToNSA).
join(sampledb.NSA)
)
returnrestwave
|
and this fails
|
In[6]:datadb.Cube.restwave
---------------------------------------------------------------------------
ArgumentError Traceback(most recent call last)
<ipython-input-6-16300d165395>in<module>()
---->1datadb.Cube.restwave
/Users/Brian/anaconda2/lib/python2.7/site-packages/sqlalchemy/ext/hybrid.pyc
in__get__(self,instance,owner)
738 def__get__(self,instance,owner):
739 ifinstance isNone:
-->740 returnself.expr(owner)
741 else:
742 returnself.fget(instance)
/Users/Brian/Work/sdss/repo/sdss/sdss_python_module/marvin/python/sdss/internal/database/utah/mangadb/DataModelClasses.pyc
inrestwave(cls)
454 # unwave =
select([(func.unnest(Wavelength.wavelength)/(1+sampledb.NSA.z)).label('restw')])
455 # restwave =
select([func.array_agg(unwave.c.restw).label('restwarr')]).select_from(
-->456 # Cube.__table__.join(Wavelength.wavelength).
457 # join(sampledb.MangaTarget).
458 # join(sampledb.MangaTargetToNSA).
/Users/Brian/anaconda2/lib/python2.7/site-packages/sqlalchemy/sql/selectable.pyc
injoin(self,right,onclause,isouter)
350 """
351
--> 352 return Join(self, right, onclause, isouter)
353
354 def outerjoin(self, right, onclause=None):
/Users/Brian/anaconda2/lib/python2.7/site-packages/sqlalchemy/sql/selectable.pyc
in __init__(self, left, right, onclause, isouter)
658 """
659 self.left =_interpret_as_from(left)
-->660 self.right =_interpret_as_from(right).self_group()
661
662 ifonclause isNone:
/Users/Brian/anaconda2/lib/python2.7/site-packages/sqlalchemy/sql/selectable.pyc
in_interpret_as_from(element)
47 returninsp.selectable
48 exceptAttributeError:
--->49 raiseexc.ArgumentError("FROM expression expected")
50
51
ArgumentError:FROM expression expected
|
--
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
<mailto:sqlalchemy+unsubscr...@googlegroups.com>.
To post to this group, send email to sqlalchemy@googlegroups.com
<mailto:sqlalchemy@googlegroups.com>.
Visit this group at https://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 https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.