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

时间:2010-06-08 21:28:09

标签: python sql-server-2000 sqlalchemy pyodbc freetds

我通过pyodbc连接到mssql服务器,通过FreeTDS odbc驱动程序,在linux ubuntu 10.04上。

Sqlalchemy 0.5对DATETIME字段使用sqlalchemy.Date()

现在Sqlalchemy 0.6使用DATE,但sql server 2000没有DATE类型。如何使DATETIME成为sqlalchemy 0.6 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 个答案:

答案 0 :(得分:0)

这种情况应该由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(...)方法。

答案 1 :(得分:0)

我明白了 - 我的配置错了。

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

我已经在freetds.conf文件上正确设置了,但是这个文件没有被读取,因为它只在您使用文件中定义的DSN时被解析,而我正在使用连接字符串。问题中的例子。

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

答案 2 :(得分:0)

你是如何进行迁移的?

我使用mssqlsucks在同一条船上。 这是我的解决方案。

配置

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

我的 init .py(其中是underbars?)

我遇到了很多编码问题,我最终做到了这一点,而且似乎有效。我很想看看你最终做了什么。

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)