我似乎无法在Postgres中正确存储unicode字符。它们显示为代码表示,例如例如<C3><A5>
而不是å
。
我的数据库是使用UTF-8作为编码创建的。我试过用psycopg2存储unicode字符串,如下所示:
field = myUnicodeString.encoding('utf-8')
cursor.execute("INSERT INTO mytable (column1) VALUES (%s)", (field))
field = myUnicodeString
cursor.execute("INSERT INTO mytable (column1) VALUES (%s)", (field))
但两个替代品都存储不正确的字符。我是否也需要为表格设置字符集,或问题是什么?
更新1:
我发现我甚至无法在终端中键入非ascii字符 - 比如å,ä和ö。我在Ubuntu 12.04服务器上。这可能与服务器本身的语言设置有关吗?
更新2
我现在能够在SSH会话期间在终端中键入非ascii字符。我更改了区域设置并重新启动了服务器。此外,我能够在我的UTF-8数据库中手动存储非ascii字符(在psql中:INSERT INTO table (column) VALUES ('ö')
)。 char在psql中正确显示。
当我SELECT convert_to(column, 'utf-8') FROM table
在表中手动插入行时,char ö
在psql中显示为\xc383c2b6
。
当我在Python中print repr('ö')
时,我得到'\xc3\xb6'
。我真的想了解如何调试这个,但我不确定该寻找什么。
答案 0 :(得分:2)
目前尚不清楚您是否错误地确认了存储字符 。也不清楚问题是在PostgreSQL中使用它们,还是在Python之前使用它们。
在这种情况下,“å”是unicode代码点U + 00E5,在utf-16 BE中编码为0x00E5或在utf-8中编码为0xc3 0xa5。这符合你所看到的 - 一个utf-8字节序列表示“å” - 所以我怀疑你的终端配置错误,无法显示它,或者试图把它解释为latin-1而没有生成的错位文本字体中的正确字符:
>>> print u'å'.encode("utf-8").decode("latin-1")
Ã¥
所以它显示了代码点。
您的Python代码无意义无效:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute 'encoding'
我认为你的意思是“编码”。无论如何都没必要这样做; Python psycopg2
很高兴直接使用unicode
字符串对象:
>>> conn = psycopg2.connect("dbname=regress")
>>> curs = conn.cursor()
>>> curs.execute("SELECT %s", (u'áéíóú',));
>>> print curs.fetchone()[0]
áéíóú
对于编码问题,您需要逐步跟踪事项,以确定文本编码被错误处理的位置。
没有足够的信息来回答这样的问题。我真正能提供的只是一般建议。在每一步中,确认您尊重输入的编码,并确保一步的输出采用相同的编码,下一步期望作为输入。
首先,您需要确保您的unicode字符串在Python中是正确的。 print repr(mystring)
对此有用,可以查看字符串数据。然后你应该在将它们传递给psycopg2
时停止显式编码;让psycopg2
处理它。
下一步是使用psql
在数据库中检查它们。即使它们无法在终端上正确显示,您也可以使用convert_to
函数检查它们是否在数据库中,该函数将数据库字段或字符串文字作为输入,并以所需的编码输出字节序列。所以,例如:
SELECT convert_to(column1, 'utf-8') FROM mytable;
并确保返回的十六进制字节序列与您发送的文本的utf-8编码应该匹配。
继续此过程。在每一步中,检查字符串字节以确保它们匹配应该是什么,直到找到错误处理文本的阶段。
我向你保证,PostgreSQL和psycopg2
都不会错误地存储Unicode字符。在这种情况下,它可能是一个简单的问题,因为您的终端设置错误,或者可能是文本处理路径中的某些内容使用了错误的输入编码,因此您将某些内容编码为utf-8,然后将其解码为拉丁语 - 1(例如)。