如何使用SQLAlchemy保存unicode?

Gil*_*tes 6 python unicode sqlalchemy

我遇到过这样的错误:

File "/vagrant/env/local/lib/python2.7/site-packages/sqlalchemy/engine/default.py", line 435, in do_execute
            cursor.execute(statement, parameters)
        exceptions.UnicodeEncodeError: 'ascii' codec can't encode character u'\u2013' in position 8410: ordinal not in range(128)
Run Code Online (Sandbox Code Playgroud)

当我试图用指定的Python unicode字符串保存ORM对象时,就会发生这种情况.因此dict parameters,将unicode字符串作为其值之一,并在将其强制转换为str类型时产生错误.

我试图convert_unicode=True设置引擎和列的设置,但没有成功.

那么在SQLAlchemy中处理unicode的好方法是什么?

UPDATE

这是关于我的设置的一些细节:

表:

                                    Table "public.documents"
   Column   |           Type           |                       Modifiers                        
------------+--------------------------+--------------------------------------------------------
 id         | integer                  | not null default nextval('documents_id_seq'::regclass)
 sha256     | text                     | not null
 url        | text                     | 
 source     | text                     | not null
 downloaded | timestamp with time zone | not null
 tags       | json                     | not null
Indexes:
    "documents_pkey" PRIMARY KEY, btree (id)
    "documents_sha256_key" UNIQUE CONSTRAINT, btree (sha256)
Run Code Online (Sandbox Code Playgroud)

ORM模型:

class Document(Base):
    __tablename__ = 'documents'

    id = Column(INTEGER, primary_key=True)
    sha256 = Column(TEXT(convert_unicode=True), nullable=False, unique=True)
    url = Column(TEXT(convert_unicode=True))
    source = Column(TEXT(convert_unicode=True), nullable=False)
    downloaded = Column(DateTime(timezone=True), nullable=False)
    tags = Column(JSON, nullable=False)
Run Code Online (Sandbox Code Playgroud)

SQLAlchemy设置:

ENGINE = create_engine('postgresql://me:secret@localhost/my_db',
                       encoding='utf8', convert_unicode=True)
Session = sessionmaker(bind=ENGINE)
Run Code Online (Sandbox Code Playgroud)

产生错误的代码只是创建一个会话,实例化一个Document对象并使用分配给它的source字段withunicode`trign保存它.

更新#2

检查 repo - 它具有自动Vagrant/Ansible设置,并重现此错误.

Gun*_*iem 10

你的问题在这里:

$ sudo grep client_encoding /etc/postgresql/9.3/main/postgresql.conf
client_encoding            = sql_ascii
Run Code Online (Sandbox Code Playgroud)

这导致psycopg2默认为ASCII:

>>> import psycopg2
>>> psycopg2.connect('dbname=dev_db user=dev').encoding
'SQLASCII'
Run Code Online (Sandbox Code Playgroud)

...它有效地关闭了psycopg2处理Unicode的能力.

您可以在postgresql.conf中修复此问题:

client_encoding = utf8
Run Code Online (Sandbox Code Playgroud)

(然后sudo invoke-rc.d postgresql reload),或者您可以在创建引擎时明确指定编码:

self._conn = create_engine(src, client_encoding='utf8')
Run Code Online (Sandbox Code Playgroud)

我推荐前者,因为九十年代初期早已不复存在.:)