代码之家  ›  专栏  ›  技术社区  ›  nosklo

使用mssql的0.6迁移中的sqlalchemy日期类型

  •  0
  • nosklo  · 技术社区  · 14 年前

    我通过pyodbc连接到mssql服务器,通过FreeTDS-odbc驱动程序,在linux-ubuntu10.04上。

    Sqlalchemy 0.5使用 DATETIME 对于 sqlalchemy.Date()

    现在Sqlalchemy 0.6使用 DATE ,但sql server 2000没有 日期 类型。我该怎么做 日期时间 是的默认值 sqlalchemy.Date() mssql+pyodbc 方言?

    下面是重现问题的代码:

    import sqlalchemy
    from sqlalchemy import Table, Column, MetaData, Date, Integer, create_engine
    
    engine = create_engine(
        'mssql+pyodbc://sa:sa@myserver/mydb?driver=FreeTDS')
    
    m = MetaData(bind=engine)
    
    tb = sqlalchemy.Table('test_date', m, 
        Column('id', Integer, primary_key=True),
        Column('dt', Date())
    )
    tb.create()
    

    Traceback (most recent call last):
      File "/tmp/teste.py", line 15, in <module>
        tb.create()
      File "/home/nosklo/.local/lib/python2.6/site-packages/sqlalchemy/schema.py", line 428, in create
        bind.create(self, checkfirst=checkfirst)
      File "/home/nosklo/.local/lib/python2.6/site-packages/sqlalchemy/engine/base.py", line 1647, in create
        connection=connection, **kwargs)
      File "/home/nosklo/.local/lib/python2.6/site-packages/sqlalchemy/engine/base.py", line 1682, in _run_visitor
        **kwargs).traverse_single(element)
      File "/home/nosklo/.local/lib/python2.6/site-packages/sqlalchemy/sql/visitors.py", line 77, in traverse_single
        return meth(obj, **kw)
      File "/home/nosklo/.local/lib/python2.6/site-packages/sqlalchemy/engine/ddl.py", line 58, in visit_table
        self.connection.execute(schema.CreateTable(table))
      File "/home/nosklo/.local/lib/python2.6/site-packages/sqlalchemy/engine/base.py", line 1157, in execute
        params)
      File "/home/nosklo/.local/lib/python2.6/site-packages/sqlalchemy/engine/base.py", line 1210, in _execute_ddl
        return self.__execute_context(context)
      File "/home/nosklo/.local/lib/python2.6/site-packages/sqlalchemy/engine/base.py", line 1268, in __execute_context
        context.parameters[0], context=context)
      File "/home/nosklo/.local/lib/python2.6/site-packages/sqlalchemy/engine/base.py", line 1367, in _cursor_execute
        context)
      File "/home/nosklo/.local/lib/python2.6/site-packages/sqlalchemy/engine/base.py", line 1360, in _cursor_execute
        context)
      File "/home/nosklo/.local/lib/python2.6/site-packages/sqlalchemy/engine/default.py", line 277, in do_execute
        cursor.execute(statement, parameters)
    sqlalchemy.exc.ProgrammingError: (ProgrammingError) 
    ('42000', '[42000] [FreeTDS][SQL Server]Column or parameter #2: 
    Cannot find data type DATE. (2715) 
    (SQLExecDirectW)') 
    '\nCREATE TABLE test_date (\n\tid INTEGER NOT NULL IDENTITY(1,1), 
    \n\tdt DATE NULL, \n\tPRIMARY KEY (id)\n)\n\n' ()
    
    3 回复  |  直到 14 年前
        1
  •  0
  •   van    14 年前

    这种情况应该由sqlalchemy妥善处理。 MS SQL - Date / Time Handling .

    mssql\base.py ):

    def visit_date(self, type_):
        if self.dialect.server_version_info < MS_2008_VERSION:
            return self.visit_DATETIME(type_)
        else:
            return self.visit_DATE(type_)
    

    我的建议是调试代码并检查 MSTypeCompiler 如果你击中 visit_date(...) 方法。

        2
  •  0
  •   nosklo    14 年前

    事实证明,您必须配置freetds以使其使用TDS协议的7.0或8.0版本。默认情况下,它使用4.2,在查询mssqlserver版本时会产生奇怪的结果,导致SQLAlchemy行为混乱,正如我在问题中所描述的那样。

    我把它正确地放在桌子上了 freetds.conf 文件,但这个文件没有被读取,因为只有在使用文件中定义的DSN时,它才会被解析,而我使用的是连接字符串,如问题中的示例所示。

    设置变量 TDSVER 如前所述 here 解决了这个问题。

        3
  •  0
  •   Chet Meinzer    10 年前

    我和使用mssqlsucks是同一条船。 这是我的解决办法。

    配置

    SQLALCHEMY_DATABASE_URI = 'mssql+pyodbc://dashboarddata'
    SQLALCHEMY_MIGRATE_REPO = os.path.join(basedir, 'db_repository')
    

    .py(车底在哪里?)

    我在编码方面遇到了很多问题,最后我还是这么做了,而且似乎很管用。我很想看看你最后做了什么。

    class HackedSQLAlchemy(SQLAlchemy):
        def apply_driver_hacks(self, app, info, options):
            print "Applying driver hacks"
            super(HackedSQLAlchemy, self).apply_driver_hacks(app, info, options)
            options["supports_unicode_binds"] = False
            # import pdb
            # pdb.set_trace()
    @app.template_filter('reverse')
    def reverse_filter(s):
        if s > datetime.date.today():
          return 0
        else:
           return 1
    
    db = HackedSQLAlchemy(app)