mssql db和sqlalchemy中表/列的Unicode名称

时间:2014-04-17 12:10:14

标签: unicode sqlalchemy pymssql

我正在使用最新的sqlalchemy和来自pip的最新pymssql连接mssql server 8.00.2039(2005?)难度是表和列名称是俄语。是否可以使用sqlalchemy处理此数据库?至少我必须让'select ... where'查询。

engine = create_engine("mssql+pymssql://%s:%s@RTBD/rt?charset=utf8" % (settings.RT_USER, settings.RT_PWD), echo = True, encoding = 'utf8')
metadata = MetaData()
metadata.reflect(engine, only = [u"Заказы",])
orders = metadata.tables[u'Заказы']
res = engine.execute(orders.select(orders.c[u'Номер заказа'] == u'14-01-0001'))

例外是

ValueError                                Traceback (most recent call last)
<ipython-input-8-50ce93243d1c> in <module>()
----> 1 engine.execute(orders.select(orders.c[orders.columns.keys()[0]] == u'14-01-0001'))

python2.7/site-packages/sqlalchemy/engine/base.pyc in execute(self, statement, *multiparams, **params)
   1680 
   1681         connection = self.contextual_connect(close_with_result=True)
-> 1682         return connection.execute(statement, *multiparams, **params)
   1683 
   1684     def scalar(self, statement, *multiparams, **params):

python2.7/site-packages/sqlalchemy/engine/base.pyc in execute(self, object, *multiparams, **params)
    718                                 type(object))
    719         else:
--> 720             return meth(self, multiparams, params)
    721 
    722     def _execute_function(self, func, multiparams, params):

python2.7/site-packages/sqlalchemy/sql/elements.pyc in _execute_on_connection(self, connection, multiparams, params)
    315 
    316     def _execute_on_connection(self, connection, multiparams, params):
--> 317         return connection._execute_clauseelement(self, multiparams, params)
    318 
    319     def unique_params(self, *optionaldict, **kwargs):

python2.7/site-packages/sqlalchemy/engine/base.pyc in _execute_clauseelement(self, elem, multiparams, params)
    815             compiled_sql,
    816             distilled_params,
--> 817             compiled_sql, distilled_params
    818         )
    819         if self._has_events or self.engine._has_events:

python2.7/site-packages/sqlalchemy/engine/base.pyc in _execute_context(self, dialect, constructor, statement, parameters, *args)
    945                                 parameters,
    946                                 cursor,
--> 947                                 context)
    948 
    949         if self._has_events or self.engine._has_events:

python2.7/site-packages/sqlalchemy/engine/base.pyc in _handle_dbapi_exception(self, e, statement, parameters, cursor, context)
   1109                                 )
   1110 
-> 1111             util.reraise(*exc_info)
   1112 
   1113         finally:

python2.7/site-packages/sqlalchemy/engine/base.pyc in _execute_context(self, dialect, constructor, statement, parameters, *args)
    938                                      statement,
    939                                      parameters,
--> 940                                      context)
    941         except Exception as e:
    942             self._handle_dbapi_exception(

python2.7/site-packages/sqlalchemy/engine/default.pyc in do_execute(self, cursor, statement, parameters, context)
    433 
    434     def do_execute(self, cursor, statement, parameters, context=None):
--> 435         cursor.execute(statement, parameters)
    436 
    437     def do_execute_no_params(self, cursor, statement, context=None):

python2.7/site-packages/pymssql.so in pymssql.Cursor.execute (pymssql.c:6057)()

python2.7/site-packages/_mssql.so in _mssql.MSSQLConnection.execute_query (_mssql.c:9858)()

python2.7/site-packages/_mssql.so in _mssql.MSSQLConnection.execute_query (_mssql.c:9734)()

python2.7/site-packages/_mssql.so in _mssql.MSSQLConnection.format_and_run_query (_mssql.c:10814)()

python2.7/site-packages/_mssql.so in _mssql.MSSQLConnection.format_sql_command (_mssql.c:11042)()

python2.7/site-packages/_mssql.so in _mssql._substitute_params (_mssql.c:18359)()

<type 'str'>: (<type 'exceptions.UnicodeEncodeError'>, UnicodeEncodeError('ascii', u'params dictionary did not contain value for placeholder: \u041d\u043e\u043c\u0435\u0440 \u0437\u0430\u043a\u0430\u0437\u0430_1', 57, 62, 'ordinal not in range(128)'))

查询正确,以WHERE [Заказы].[Номер заказа] = %(Номер заказа_1)s

结束

但来自sqla的信息消息为INFO sqlalchemy.engine.base.Engine {'\xd0\x9d\xd0\xbe\xd0\xbc\xd0\xb5\xd1\x80 \xd0\xb7\xd0\xb0\xd0\xba\xd0\xb0\xd0\xb7\xd0\xb0_1': '14-01-0001'}

字符串\xd0\x9d\xd0\xbe\xd0\xbc\xd0\xb5\xd1\x80 \xd0\xb7\xd0\xb0\xd0\xba\xd0\xb0\xd0\xb7\xd0\xb0_1\u041d\u043e\u043c\u0435\u0440 \u0437\u0430\u043a\u0430\u0437\u0430_1等于Номер заказа_1

1 个答案:

答案 0 :(得分:2)

如邮件列表中所述,FreeTDS等对此非常挑剔。以下测试适用于我,但对于上面的海报,它不起作用:

  1. UnixODBC 2.3.0
  2. FreeTDS 0.91
  3. Pyodbc 3.0.7
  4. Linux,而不是OSX,OSX在tds / pyodbc上有很多问题,我在这台Fedora 14机器上运行
  5. Freetds设置:

    [sqlserver_2008_vmware]
            host = 172.16.248.142
            port = 1213
            tds version = 7.2
            client charset = UTF8
            text size = 50000000
    

    测试脚本:

    # coding: utf-8
    from sqlalchemy import create_engine, MetaData, Table, Column, String
    
    e = create_engine("mssql+pyodbc://scott:tiger@ms_2008", echo=True)
    #e = create_engine("mssql+pymssql://scott:tiger@172.16.248.142:1213", echo=True)
    
    m = MetaData()
    
    t = Table(u'Заказы', m, Column(u'Номер заказа', String(50)))
    
    m.drop_all(e)
    m.create_all(e)
    
    orders = m.tables[u'Заказы']
    e.execute(orders.select(orders.c[u'Номер заказа'] == u'14-01-0001'))
    

    输出的一部分:

    CREATE TABLE [Заказы] (
        [Номер заказа] VARCHAR(50) NULL
    )
    
    
    2014-03-31 20:57:16,266 INFO sqlalchemy.engine.base.Engine ()
    2014-03-31 20:57:16,268 INFO sqlalchemy.engine.base.Engine COMMIT
    2014-03-31 20:57:16,270 INFO sqlalchemy.engine.base.Engine SELECT [Заказы].[Номер заказа] 
    FROM [Заказы] 
    WHERE [Заказы].[Номер заказа] = ?
    2014-03-31 20:57:16,270 INFO sqlalchemy.engine.base.Engine (u'14-01-0001',)