【问题标题】:Python/Django Writes u'' String To Postgresql (with UTF8 DB) and Munges EntryPython/Django 将 u'' 字符串写入 Postgresql(使用 UTF8 DB)和 Munges 条目
【发布时间】: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。
  • 您是否安装了unidecodepytils 呢?
  • 有趣...但是当我尝试添加该列时,我遇到了唯一的约束冲突。

标签: python django postgresql unicode


【解决方案1】:

Django slugify 不支持 unicode,你应该使用unicode-slugify

(在两勺 Django http://django.2scoops.org/ 中读到)

【讨论】:

  • 有趣 - 但我使用 AutoSlug 和自定义 slugifier - 这不应该绕过 Django 的默认设置吗?
  • 您的自定义 slugifier 是什么?默认情况下,它是 django 的,它没有安装 pyutils 或 unicode。这让我想到了 unicodedata 模块的 normalyze 方法。但是我无法使用默认的 4 种形式重现您的结果...
  • documentation s 中表示如果未安装 unidecode 或 pyutils,则使用默认的 django 引擎。你能用 "é" u'\xe9' 试试看它是否被翻译成 e 吗??
  • 我实际上最终使用了另一种解决方案,所以我无法对此进行测试 :(,但我肯定错过了作为文档的一部分,并且几乎可以肯定是原因!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-02-12
  • 1970-01-01
  • 1970-01-01
  • 2014-07-14
  • 2020-10-27
  • 2021-06-30
  • 2015-10-08
相关资源
最近更新 更多