On 05/22/2016 07:12 PM, Brian Cherinka wrote:

What's the proper way to return in an ORM query the value of a Postgres
array attribute at a given specific index within the array?

I have a db table with a column called value, which is a 2d array,
defined as REAL[][].

My ModelClass is defined as

|
classEmLine(Base):
    __tablename__ ='emline'
    __table_args__ ={'autoload':True,'schema':'dapdb'}

    def__repr__(self):
        return'<EmLine (pk={0})'.format(self.pk)

    value =Column(ARRAY(Float,dimensions=2,zero_indexes=True))
    ivar =Column(ARRAY(Float,dimensions=2,zero_indexes=True))
    mask =Column(ARRAY(Integer,dimensions=2,zero_indexes=True))

|

Pure SQL indexing an array works just fine
|
selecte.value[16][17]fromdapdb.emline ase;
|

But SQLalchemy does not
|
session.query(dapdb.EmLine.value[16][17]).first()
|

returns the error
|
NotImplementedError:Operator'getitem'isnotsupported on thisexpression

this is a bug that's been fixed for 1.1. It's detailed here: http://docs.sqlalchemy.org/en/latest/changelog/migration_11.html#correct-sql-types-are-established-from-indexed-access-of-array-json-hstore

For multi-dimensional access, this can be worked around for a one-off using type_coerce:

>>> from sqlalchemy import type_coerce
>>> type_coerce(c[4], ARRAY(Integer))[5]

There is also a generalized workaround created for the bug that you can see at https://bitbucket.org/zzzeek/sqlalchemy/issues/3487#comment-20200804 . It involves creation of an ARRAY subclass that does the right thing within __getitem__. That subclass can be a drop-in replacement for regular ARRAY.








|

I've tried defining a hybrid method/expression in my ModelClass, and running
|
session.query(dapdb.EmLine.singleat('value',16,17)).first()
|

 but I'm getting the same "getitem" error

|
classEmLine(Base):
    __tablename__ ='emline'
    __table_args__ ={'autoload':True,'schema':'mangadapdb'}

    def__repr__(self):
        return'<EmLine (pk={0})'.format(self.pk)

    value =Column(ARRAY(Float,dimensions=2,zero_indexes=True))
    ivar =Column(ARRAY(Float,dimensions=2,zero_indexes=True))
    mask =Column(ARRAY(Integer,dimensions=2,zero_indexes=True))

    @hybrid_method
    defsingleat(self,name,x,y):
        param =self.__getattribute__(name)
        returnparam[x][y]

    @singleat.expression
    defsingleat(cls,name,x,y):
        param =cls.__getattribute__(cls,name)
        print(param,x,y)
        returnfunc.ARRAY(param)[x][y]

|

In my singleat expression, I've tried a variety of returns.  return
func.ARRAY(param)[x][y] ;  return param[x][y].  What's the proper syntax
to match the actual SQL array indexing?



--
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.

Reply via email to