【发布时间】:2013-07-20 20:06:12
【问题描述】:
我确定我在这里配置错误,但我看不到它是什么。
在 Django 中,我有一个这样的模型字段:
short_url_slug = AutoSlugField(slugify=short_url_slugify, populate_from=id, blank=False, unique=True)
South 正确创建了迁移(看似):
'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
【问题讨论】:
-
请显示以下附加详细信息:查询
SELECT version(), current_setting('standard_conforming_strings') AS scs;的输出,以及您的 Python、Django 和 psycopg2(或您正在使用的任何 DB 适配器)版本。在postgresql.conf中打开log_statement = 'all',重新加载 PostgreSQL,并检查日志以识别 PostgreSQL 看到的可疑INSERT的文本也会非常有帮助。 -
U+00A4 (CURRENCY SIGN) 与 U+00D4 (LATIN CAPITAL LETTER LETTER O WITH CIRCUMFLEX) 完全不同,
o绝对是一个有效的 slugification。 -
您是否安装了
unidecode?pytils呢? -
有趣...但是当我尝试添加该列时,我遇到了唯一的约束冲突。
标签: python django postgresql unicode