I'm hoping that some of the functionality I actually like in appengine datastore can be duplicated in postgresql via sqlalchemy. However I'm not quite grokking how all the moving pieces for a dialect(if that's the right term) fit together.

On appengine there are list properties or repeated properties. This is simply an array of values that has a custom behavior for the "=" in a query. In that an object with a property named my_list who's value is [1,2,3] will be true in the following where clauses...

  • where my_list=1
  • where my_list=2
  • where my_list=3

I feel like it is possible to get the same kind of behavior on postgresql with the ARRAY column type, but I'm having trouble finding examples of how one might do this.

Here's the code I have so far.

from sqlalchemy import Column
from sqlalchemy.dialects.postgresql import ARRAY
from sqlalchemy.orm.properties import ColumnProperty
from sqlalchemy.orm import column_property



class ListComparator(ColumnProperty.ColumnComparator):
    """
    other operators as they make sense

    optimization: override set operators for one filter instead of
    multiples and'd

    todo: non-string types?
    """
    def __eq__(self, other):
        return self.__clause_element__().op("&&")(u"{%s}" % other)


def ListColumn(*args, **kw):
    """
    makes a column of an array of types args[0]
    and uses ListComparator to emulate appengine list property
    """
    if not isinstance(args[0], ARRAY):
        largs = list(args)
        largs[0] = ARRAY(args[0])
        args = tuple(largs)
    else:
        raise ValueError("%s is an array which is not allowed" % args[0])

    return column_property(Column(*args, **kw),
                           comparator_factory=ListComparator)


example usage....


class T(B):
    __tablename__ = "t"
    id = Column(Integer, primary_key=True)
     v = ListColumn(Integer)


t = T()
t.v = [1, 2]
S.add(t)
S.commit()
S.query(T).count()
S.query(T).filter(T.v==1).count()
S.query(T).filter_by(v =1).count()

An array of strings or ints works just fine for this, but any other data types I would have to convert to strings and in some cases escape for the array literal syntax in postgresql. It seems like I'm missing some piece of the puzzle in regards to how all the types in sqla relate to each other for queries. Is it the dialect the drives that, is there behavior there for ARRAY that I'm somehow missing or trying to duplicate?

link|improve this question

feedback

Know someone who can answer? Share a link to this question via email, Google+, Twitter, or Facebook.

Your Answer

 
or
required, but never shown
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.