5

I am trying to filter PostgreSQL records using SQLALchemy ORM objects based on the existence of an integer variable in an array, but I can't find the right way to do it.

DB Settings

I have a PostgreSQL table with an array of integers:

my_db=> \d test_arr;
                           Table "public.test_arr"
  Column  |   Type    |                       Modifiers
----------+-----------+-------------------------------------------------------
 id       | integer   | not null default nextval('test_arr_id_seq'::regclass)
 partners | integer[] |

The table contains some values:

my_db=> SELECT * FROM test_arr;
 id | partners
----+----------
 12 | {1,2,3}
 13 | {2,3,4}
 14 | {3,4,5}
 15 | {4,5,6}
(4 rows)

Querying the table for the rows which contains the number 2 in the partners array is done in PostgreSQL using the ANY keyword:

my_db=> SELECT * FROM test_arr WHERE 2 = ANY(partners);
 id | partners
----+----------
 12 | {1,2,3}
 13 | {2,3,4}
(2 rows)

ORM with SQLAlchemy

SQLAlchemy supports PostgreSQL arrays, and the table is represented by:

class TestArr(Base):

    __tablename__ = 'test_arr'

    # override schema elements like Columns
    id = Column('id', Integer, Sequence('test_arr_id_seq'), primary_key=True)
    partners = Column(ARRAY(Integer))

    def __init__(self, partners):
        self.partners = partners

    def __str__(self):
        return '<%d for %s>' % (self.id, str(self.partners))

The problem

How do I run the equivalent of SELECT * FROM test_arr WHERE 2 = ANY(partners); using the Pythonic object?

What have I tried

I have tried using func, like the following:

print session.query(TestArr).filter(func.any(TestArr.partners, 2)).all()

But failed with Syntax Errors:

sqlalchemy.exc.ProgrammingError: (ProgrammingError) syntax error at or near "ANY"
LINE 3: WHERE ANY(test_arr.partners, 332)

1 Answer 1

7

you can use sqlalchemy.dialects.postgresql.Any

from sqlalchemy.dialects.postgresql import Any
session.query(TestArr).filter(Any(2, TestArr.partners)).all()

or @> array operator

session.query(TestArr).filter(TestArr.partners.op('@>')([2])).all()
Sign up to request clarification or add additional context in comments.

1 Comment

Syntax I like most is using directly column expression: session.query(TestArr).filter(TestArr.partners.any(2)).all()

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.