2013-07-22 27 views
4

我確定我在這裏配置了錯誤的東西,但我看不到它是什麼。Python/Django將u''字符串寫入Postgresql(使用UTF8 DB)和Munges Entry

在Django中,我有一個說,這一個模型字段:

short_url_slug = AutoSlugField(slugify=short_url_slugify, populate_from=id, blank=False, unique=True) 

南創建遷移(貌似)正確:

'short_url_slug': ('autoslug.fields.AutoSlugField', [], {'unique_with': '()', 'max_length': '50', 'populate_from': 'None', 'blank': 'True'}), 

我的PostgreSQL的數據庫是UTF8:

\l 

(MyDBName)      | (username) | UTF8  | en_US.UTF-8 | en_US.UTF-8 | 

而且我有一個現實生活中的unicode字符:

u'\xa4' 

但是,當我寫這篇文章的數據庫,並嘗試讀出來,我得到:

In [3]: this_instance.short_url_slug 
Out[3]: u'o' 

的思考?我懷疑Postgresql需要有不同的字符編碼,但我不確定它應該是什麼(如果是)或者如何去做。

編輯帶有附加信息的

SELECT version(), current_setting('standard_conforming_strings') AS scs; 

PostgreSQL 9.2.4 on x86_64-apple-darwin11.4.2, compiled by i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.9.00), 64-bit | on 

(END) 

Python版本:

Python 2.7.2 (default, Oct 11 2012, 20:14:37) 

Django的版本:

In [2]: django.VERSION 
Out[2]: (1, 5, 1, 'final', 0) 

psycopg2:

$ pip freeze | grep psycopg2 
psycopg2==2.5 

原始日誌和PostgreSQL:

LOG: statement: UPDATE [...lots of stuff removed...] "short_url_slug" = 'o' [... rest of the stuff ...] 

所以,它看起來像它甚至沒有獲得到PostgreSQL。但是當我在插入行中斷開時,變量肯定具有unicode值。

(Pdb) response.short_url_slug 
u'\xd6' 

(這是在Python分配之後,但在此之前response.save())

多個輸出:

,我檢測到Unicode是越來越被改寫的方式爲,數據庫唯一性約束被違反。這可以在輸出該內容到模型中(與約束關閉)進行測試:

In [11]: all = Response.objects.all() 

In [12]: all[0].short_url_slug 
Out[12]: u'o' 

In [13]: all[4].short_url_slug 
Out[13]: u'o' 

In [14]: all[4].short_url_slug == all[0].short_url_slug 
Out[14]: True 
+0

請顯示以下附加詳細信息:查詢'SELECT version(),current_setting('standard_conforming_strings')AS scs;',以及您的Python,Django和psycopg2(或您使用的任何數據庫適配器)版本的輸出。在'postgresql.conf'中將'log_statement ='all''打開,重新加載PostgreSQL,並檢查日誌,以便在PostgreSQL看到它時識別嫌疑人'INSERT'的文本也會非常有幫助。 –

+0

U + 00A4(貨幣符號)與U + 00D4(帶有CIRCUMFLEX的拉丁大寫字母O)是完全不同的字符,對於其而言'o'絕對是一個有效的段落。 – icktoofay

+0

您是否安裝了'unidecode'? 'pytils'呢? – icktoofay

回答

2

Django的slugify不支持Unicode,你應該使用unicode-slugify

(如在Django http://django.2scoops.org/的兩勺讀)

+0

有趣 - 但我使用AutoSlug和自定義slugifyer - 不應該繞過Django的默認設置? – aronchick

+0

你的定製slugifyer是什麼?默認情況下它是django的一個pyutils或unicode沒有安裝。 它讓我想到了[unicodedata]中的標準化方法(http://docs.python.org/2/library/unicodedata.html#unicodedata.normalize)模塊。但我不是重複使用默認的4種形式的結果... – Belug

+0

我使用Django-Autoslug https://pypi.python.org/pypi/django-autoslug – aronchick