Я подключен к серверу mssql через pyodbc, через драйвер odbc FreeTDS, на Linux Ubuntu 10.04.

Sqlalchemy 0.5 использует DATETIME для sqlalchemy.Date() полей.

Теперь Sqlalchemy 0.6 использует DATE, но SQL Server 2000 не имеет типа DATE. Как я могу сделать DATETIME по умолчанию для sqlalchemy.Date() на диалекте sqlalchemy 0.6 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' ()
0
nosklo 9 Июн 2010 в 01:28

3 ответа

Лучший ответ

Я понял - моя конфигурация была неверной.

Оказывается, вам нужно настроить freetds, чтобы он использовал версию 7.0 или 8.0 протокола TDS. По умолчанию он использует 4.2, что дает странные результаты при запросе версии MS SQL Server, что приводит к путанице в SQLAlchemy, как я описал в своем вопросе.

Я правильно установил файл freetds.conf, но этот файл не читался, потому что он анализируется только при использовании DSN, определенного в файле, и я использовал строку подключения, как в примере в вопрос.

Установка переменной TDSVER, как описано здесь, решила проблему.

0
nosklo 10 Июн 2010 в 22:56

Как вы делаете миграции!?

Я в одной лодке с использованием mssqlsucks. вот мое решение.

Config

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

Мой init .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)
0
Chet Meinzer 4 Июн 2014 в 22:48

Эта ситуация должна быть должным образом обработана sqlalchemy. См. MS SQL - обработка даты / времени,

Вы также можете получить фрагмент реализации, которая занимается этим (см. 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(...).

0
van 10 Июн 2010 в 08:15