2017-05-11 21 views
1

私はPostgreSQLのテーブルに、タグの配列(タグの列の配列データ型)を持つカラムを持っています。 Peewee(PythonのORM)を使用して、タグのいずれかがリスト内の任意の文字列の部分/部分文字列と一致するすべての行を選択したいと思います。LIKE Peeweeを使用した配列のSQLクエリー

ので、例えば、私はこのようになりますリストかもしれない:

["stan", "tina"] 

をし、それがタグafghanistanpakistanstanfordまたはargentinaのいずれかを持っているテーブル内のすべての行と一致する必要があります。

SQLクエリは、次のようなものになります:

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

私はこの使用してピーウィーを行うだろうか?

tags列は次のようにモデル化されている:あなたのモデルを仮定し

tags = ArrayField(TextField) 

答えて

2

ようなタグフィルタを生成する配列フィールドを持つサブクエリ unnested

from peewee import fn 

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

を作成

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


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

のように見えます10

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の2で、それはbuilt-in

+0

こんにちはいる間はPython 3reduce機能がfunctools moduleで入手可能ですに!私は全体のタグがマッチしたときにあなたのサンプルワークを得るだけです。私は、 'tags'モデルが' ArrayField(TextField) 'であるため、' contains() 'は配列が部分文字列ではなくタグと完全に一致するかどうかをチェックするだけなので、 (私はその事件を明らかにするために質問を編集しました:列の型は 'ArrayField(TextField)'です) –

+0

@AlfredGodoy:編集、それが役に立ったら –

+0

nah、まだ完全なタグと一致しています。 Peeweeによって生成されたSQLを見ると 'contains_any()'は 'WHERE t1。 'というタグになります。' &&%s'は '&& 'を意味します。私の場合、 'tags'リストには完全なタグではなく部分文字列/部分が含まれています。だから、タグ "イスタンブール"は、タグリストに "スタン"を持っていることで一致しません。 –

関連する問題