SQLAlchemy: how to filter on PgArray column types?

前端 未结 1 1218
梦毁少年i
梦毁少年i 2020-12-16 22:07

In pure postgres we can write:

SELECT * FROM my_table WHERE 10000 = ANY (array_field);

or



        
相关标签:
1条回答
  • 2020-12-16 22:57

    a = ANY(b_array) is equivalent to aIN(elements_of_b_array)1.

    Therefore you can use the in_() method.

    I can't remember ever having used a = ALL(b_array) in all my years with PostgreSQL. Have you?


    If you are dealing with an array column and want to test whether it contains a given element (or all elements of a given array) in that column, then you can utilize PostgreSQL array operators @> (contains) or more appropriately the inverse sibling <@ (is contained by).

    Array operators carry the advantage that they can be supported with a GIN index on the array column (unlike the ANY construct).

    Your SQL statement:

    SELECT * FROM my_table WHERE 10000 = ANY (array_field);
    

    is (almost)1 equivalent to

    SELECT * FROM my_table WHERE 10000 <@ array_field;
    

    I am no expert with SQLAlchemy, but according to the tutorial in the SQLAlchemy manual, you can use any operator:

    If you have come across an operator which really isn’t available, you can always use the op() method; this generates whatever operator you need:

    >>> print users.c.name.op('tiddlywinks')('foo') users.name tiddlywinks :name_1
    

    Bold emphasis mine. Your statement could look like this in SQLA:

    s = select([my_table], array_field.op('@>')('ARRAY[10000]'))
    

    Or with alternative input syntax for PostgreSQL array values:

    s = select([my_table], array_field.op('@>') (cast('{10000}', int[])))
    

    1 There is a subtle difference with NULL handling:

    SELECT '{NULL}'::int[] <@ ... -- that's an array with a single NULL element
    

    always yields FALSE.

    SELECT NULL IN (...)
    SELECT NULL = ANY (...)
    SELECT NULL::int[] <@ ...
    

    always yield NULL.

    If you are not going to query for NULL values, you can ignore this.

    0 讨论(0)
提交回复
热议问题