2012-01-18 61 views
3

我想用查詢標記我的表字段。Django。 PostgreSQL的。 regexp_split_to_table不起作用

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() 

...不能恢復令牌:

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

,當我在psql外殼執行它,但是當我做這工作。我究竟做錯了什麼?

+0

似乎psycopg doent執行Postgres的功能。 – mossplix 2012-01-18 08:30:07

+0

對Django不太瞭解,但這裏有個想法:「SELECT * FROM(SELECT regexp_split_to_table(fld,E'\\ s +')FROM tbl LIMIT 20)x LIMIT 20」。如果Django不明白函數可以返回一組值。 – 2012-01-18 08:41:26

+0

也不起作用。說一個字段是「SOPA中斷」,它不會返回[(「SOPA」,「blackout」)],但會返回[(「SOPA blackout」)] – mossplix 2012-01-18 09:30:38

回答

3

反斜槓被Django視爲元字符,並在雙引號內解釋。 因此,在字符串到達​​PostgreSQL服務器之前,E'\\s+')的一層會被剝離,該服務器將會看到E'\s+')。轉義字符串將導致'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 FFunc新和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])