1 votes

type de date sqlalchemy dans la migration 0.6 avec mssql

Je me connecte au serveur mssql par pyodbc, via le pilote odbc FreeTDS, sur linux ubuntu 10.04.

Sqlalchemy 0.5 utilise DATETIME para sqlalchemy.Date() champs.

Maintenant, Sqlalchemy 0.6 utilise DATE mais sql server 2000 ne dispose pas d'un système de gestion de la qualité. DATE type. Comment puis-je faire DATETIME être la valeur par défaut pour sqlalchemy.Date() sur sqlalchemy 0.6 mssql+pyodbc dialecte ?

J'aimerais le garder aussi propre que possible.

Voici le code permettant de reproduire le problème :

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()

Et voici le retour de trace que je reçois :

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' ()

0voto

van Points 18052

Cette situation est censée être correctement gérée par sqlalchemy. Voir MS SQL - Manipulation de la date et de l'heure .

Vous pouvez également consulter l'extrait de l'implémentation qui gère cela (voir 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_)

Ma suggestion est de déboguer votre code et de vérifier si cette MSTypeCompiler est utilisé et si vous touchez le visit_date(...) méthode.

0voto

nosklo Points 75862

Je l'ai eu - ma configuration était mauvaise.

Il s'avère que vous devez configurer freetds pour qu'il utilise la version 7.0 ou 8.0 du protocole TDS. Par défaut, il utilise la version 4.2, ce qui donne des résultats étranges lors de l'interrogation de la version de MS SQL Server, conduisant SQLAlchemy à un comportement confus, comme je l'ai décrit dans ma question.

Je l'avais correctement réglé sur le freetds.conf mais ce fichier n'était pas lu, car il n'est analysé que lorsque vous utilisez un DSN défini dans le fichier, et j'utilisais une chaîne de connexion comme dans l'exemple de la question.

Définition de la variable TDSVER comme décrit aquí a résolu le problème.

0voto

Chet Meinzer Points 187

Comment faites-vous les migrations ?

Je suis dans le même bateau en utilisant mssqlsucks. Voici ma solution.

config

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

mon init .py (où sont les barres inférieures ?)

J'avais tellement de problèmes d'encodage que j'ai fini par faire ça, et ça semble fonctionner. J'aimerais bien voir ce que vous avez fini par faire.

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)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X