2012-01-18 12 views
3

Я пытаюсь tokenize мои поля таблицы с запросом.Django. PostgreSQL. regexp_split_to_table не работает

SELECT regexp_split_to_table(mytable.field_name, E'\\s+') from mytable limit 20; 

Это работает, когда я исполню ее из Psql оболочки, но когда я делаю:

from django.db import connection cursor=connection.cursor() 
cursor.execute("SELECT regexp_split_to_table(mytable.field_name,E'\\s+') 
       FROM mytable LIMIT 20") 
cursor.fetchall() 

... он не возвращает лексемы. Что я делаю не так?

+0

это кажется Psycopg doent выполнять Postgres функции. – mossplix

+0

Не знаю много о Django, но вот идея: «SELECT * FROM (SELECT regexp_split_to_table (fld, E '\\ s +') FROM tbl LIMIT 20) x LIMIT 20". В случае, если Django не понимает, что функция может возвращать набор значений. –

+0

тоже не работает. скажем, в полях «SOPA blackout», он не вернется [(«SOPA», «затемнение»)], но вернется [(«SOPA затемнение»)] – mossplix

ответ

3

Обратная косая черта рассматривается как метасимвол Django и интерпретируется внутри двойных кавычек. Итак, один слой E'\\s+') стрижен до того, как строка прибудет на сервер PostgreSQL, который увидит E'\s+'). Строка escape приведет к 's+', который, в свою очередь, сделает regexp_split_to_table(), разделив ваши строки на любое количество s вместо непечатного пространства, которое сокращает класс символов \s в регулярных выражениях.

Двойные ваши обратные косые в строке, чтобы получить то, что вы хотели: E'\\\\s+'):

"SELECT regexp_split_to_table(field_name, E'\\\\s+') FROM mytable LIMIT 20" 

В качестве альтернативы, чтобы избежать проблем с особым значением обратной косой черты \, вы можете использовать [[:space:]] для обозначения того же символа класс:

"SELECT regexp_split_to_table(field_name, '[[:space:]]+') FROM mytable LIMIT 20" 

подробности в главе "Pattern Matching" in the manual.

1

Благодаря новым в Django F, Func и Supprot для PostgreSQL ArrayField теперь вы можете вызвать эту функцию следующим образом:

from django.db.models import F, Value, TextField 
from django.contrib.postgres.fields import ArrayField 
from django.db.models.expressions import Func 

MyTable.objects.annotate(
    some_field_splitted=Func(
     F('some_field'), 
     Value(","), 
     function='regexp_split_to_array', 
     output_field=ArrayField(TextField()) 
    ) 
).filter(some_field_splitted__contains=[HERE_SOME_VALUE]) 
Смежные вопросы