使用Peewee在数组上进行SQL查询

时间:2017-05-11 08:06:25

标签: python postgresql peewee

我有一个PostgreSQL表,其中包含一个带有标记数组的列(标记列中的数组数据类型)。使用Peewee(python ORM),我想选择任何标记与列表中任何字符串的part / substring匹配的所有行。

因此,例如,我可以有一个如下所示的列表:

["stan", "tina"]

并且应该匹配表格中包含任何标记afghanistanpakistanstanfordargentina的所有行。

SQL查询可能如下所示:

SELECT * FROM media WHERE tags::text LIKE ANY (ARRAY[‘%stan%‘, ‘%tina%‘]);

我如何使用Peewee做到这一点?

tags列的建模如下:

tags = ArrayField(TextField)

1 个答案:

答案 0 :(得分:2)

假设您的模型看起来像

from peewee import Model, TextField
from playhouse.postgres_ext import ArrayField


class Media(Model):
    tags = ArrayField(TextField)

使用数组字段unnested

创建子查询
from peewee import fn

subquery = (Media.select(Media.id.alias('id'),
                         fn.unnest(Media.tags).alias('unnested_tags'))
            .alias('subquery'))

生成标签过滤器,如

tags = ["stan", "tina"]
tags_filters = [subquery.c.unnested_tags.contains(tag) for tag in tags]
tags_filter = reduce(operator.or_, tags_filters)

,最终查询将是

query = (Media.select().join(subquery,
                             on=subquery.c.id == Media.id)
         .filter(tags_filter)
         # gets rid of duplicates
         .group_by(Media.id))

P上。 S。 Python 3 reduce函数在functools module可用,而在 Python 2 中则为built-in