Hi Mike:

Thank you for that. I will try it out on Monday.

I see there is a major refactoring around types in version 0.6. One
would be expected to define table classes with generic SQL types like
CHAR or generic "language" types like String and not with dialect
implementations like OracleChar. Am I right in that?

Still it would be nice understand why the "monkey patch" did not work
but it is probably not the best use of your time or mine. Thanks again
for the prompt fix and I will be upgrading to 0.6.

V.

On Oct 3, 4:02 pm, Michael Bayer <mike...@zzzcomputing.com> wrote:
> On Oct 2, 2009, at 6:05 PM, volx wrote:
>
>
>
> > My module is called sandbox.py
> > After importing it to ipython and letting it run, here's what I get
> > for the test you suggested:
>
> > In [47]: (sandbox.price_sources.c.desciption=='EJV').right.type
> > Out[47]: OracleChar(length=100, convert_unicode=False,
> > assert_unicode=None)
>
> > The trouble that for some reason the code goes into
> > sqlalchemy.types.String.get_dbapi_type instead of
> > sqlalchemy.databases.oracle.OracleChar
>
> I added an _OracleChar type to the oracle dialect in trunk (0.6) which  
> provides dbapi.FIXED_CHAR.   I was able to reproduce your original  
> behavior, added a unit test which exercises the select lookup on the  
> CHAR column both with a straight Table as well as a reflected one, and  
> it all passes.  There was no issue with the get_dbapi_type()  
> mechanism.   That is in r6386.
>
> test:
>
>          m = MetaData(testing.db)
>          t = Table('t1', m,
>              Column('id', Integer, primary_key=True),
>              Column('data', CHAR(30), nullable=False)
>          )
>
>          t.create()
>          try:
>              t.insert().execute(
>                  dict(id=1, data="value 1"),
>                  dict(id=2, data="value 2"),
>                  dict(id=3, data="value 3")
>              )
>
>              eq_(t.select().where(t.c.data=='value 2').execute
> ().fetchall(),
>                  [(2, 'value 2                       ')]
>                  )
>
>              m2 = MetaData(testing.db)
>              t2 = Table('t1', m2, autoload=True)
>              assert type(t2.c.data.type) is CHAR
>              eq_(t2.select().where(t2.c.data=='value 2').execute
> ().fetchall(),
>                  [(2, 'value 2                       ')]
>                  )
>
>          finally:
>              t.drop()
>
>
>
>
>
> > In [14]: pdb.run('sandbox.test()')
> >> <string>(1)<module>()
> > (Pdb) b /usr/local/lib/python2.6/site-packages/SQLAlchemy-0.5.5-
> > py2.6.egg/sqlalchemy/engine/default.py:322
> > Breakpoint 7 at /usr/local/lib/python2.6/site-packages/
> > SQLAlchemy-0.5.5-py2.6.egg/sqlalchemy/engine/default.py:322
> > (Pdb) c
> > 2009-10-02 17:58:18,020 INFO sqlalchemy.engine.base.Engine.0x...97ec
> > SELECT USER FROM DUAL
> > 2009-10-02 17:58:18,020 INFO sqlalchemy.engine.base.Engine.0x...97ec
> > {}
> > 2009-10-02 17:58:18,025 INFO sqlalchemy.engine.base.Engine.0x...97ec
> > select table_name from all_tables where table_name=:name and
> > owner=:schema_name
> > 2009-10-02 17:58:18,026 INFO sqlalchemy.engine.base.Engine.0x...97ec
> > {'name': 'VICTOR_PRICE_SOURCES', 'schema_name': 'CDOCOLLAT'}
> >> /usr/local/lib/python2.6/site-packages/SQLAlchemy-0.5.5-py2.6.egg/
> >> sqlalchemy/engine/default.py(322)set_input_sizes()
> > -> dbtype = typeengine.dialect_impl(self.dialect).get_dbapi_type
> > (self.dialect.dbapi)
> > (Pdb) dbtype
> > *** NameError: name 'dbtype' is not defined
> > (Pdb) typeengine.dialect_impl(self.dialect)
>
> > OracleChar(length=100, convert_unicode=False, assert_unicode=None)
>
> > (Pdb) # we should be going into OracleChar.get_dbapi_type
>
> > *** SyntaxError: unexpected EOF while parsing (<stdin>, line 1)
> > (Pdb) s
> > --Call--
> >> /usr/local/lib/python2.6/site-packages/SQLAlchemy-0.5.5-py2.6.egg/
> >> sqlalchemy/types.py(124)dialect_impl()
> > -> def dialect_impl(self, dialect, **kwargs):
> > (Pdb) l
> > 119               Column('data', MyType(16))
> > 120               )
> > 121
> > 122         """
> > 123
> > 124  ->     def dialect_impl(self, dialect, **kwargs):
> > 125             try:
> > 126                 return self._impl_dict[dialect]
> > 127             except AttributeError:
> > 128                 self._impl_dict = weakref.WeakKeyDictionary()   #
> > will be optimized in 0.6
> > 129                 return self._impl_dict.setdefault(dialect,
> > dialect.type_descriptor(self))
> > (Pdb) l
> > 130             except KeyError:
> > 131                 return self._impl_dict.setdefault(dialect,
> > dialect.type_descriptor(self))
> > 132
> > 133         def __getstate__(self):
> > 134             d = self.__dict__.copy()
> > 135             d.pop('_impl_dict', None)
> > 136             return d
> > 137
> > 138         def get_col_spec(self):
> > 139             """Return the DDL representation for this type."""
> > 140             raise NotImplementedError()
> > (Pdb) dialect
> > <sqlalchemy.databases.oracle.OracleDialect object at 0xa1ae54c>
> > (Pdb) n
> >> /usr/local/lib/python2.6/site-packages/SQLAlchemy-0.5.5-py2.6.egg/
> >> sqlalchemy/types.py(125)dialect_impl()
> > -> try:
> > (Pdb) n
> >> /usr/local/lib/python2.6/site-packages/SQLAlchemy-0.5.5-py2.6.egg/
> >> sqlalchemy/types.py(126)dialect_impl()
> > -> return self._impl_dict[dialect]
> > (Pdb) n
> > --Return--
> >> /usr/local/lib/python2.6/site-packages/SQLAlchemy-0.5.5-py2.6.egg/
> >> sqlalchemy/types.py(126)dialect_impl()->OracleCh...ode=None)
> > -> return self._impl_dict[dialect]
> > (Pdb) l
> > 121
> > 122         """
> > 123
> > 124         def dialect_impl(self, dialect, **kwargs):
> > 125             try:
> > 126  ->             return self._impl_dict[dialect]
> > 127             except AttributeError:
> > 128                 self._impl_dict = weakref.WeakKeyDictionary()   #
> > will be optimized in 0.6
> > 129                 return self._impl_dict.setdefault(dialect,
> > dialect.type_descriptor(self))
> > 130             except KeyError:
> > 131                 return self._impl_dict.setdefault(dialect,
> > dialect.type_descriptor(self))
> > (Pdb) dialect
> > <sqlalchemy.databases.oracle.OracleDialect object at 0xa1ae54c>
> > (Pdb) n
> > --Call--
> >> /usr/local/lib/python2.6/site-packages/SQLAlchemy-0.5.5-py2.6.egg/
> >> sqlalchemy/types.py(477)get_dbapi_type()
> > -> def get_dbapi_type(self, dbapi):
> > (Pdb) l
> > 472                         return value
> > 473                 return process
> > 474             else:
> > 475                 return None
> > 476
> > 477  ->     def get_dbapi_type(self, dbapi):
> > 478             return dbapi.STRING
> > 479
> > 480     class Text(String):
> > 481         """A variably sized string type.
> > 482
> > (Pdb) l 1
> >  1     # types.py
> >  2     # Copyright (C) 2005, 2006, 2007, 2008, 2009 Michael Bayer
> > mike...@zzzcomputing.com
> >  3     #
> >  4     # This module is part of SQLAlchemy and is released under
> >  5     # the MIT License:http://www.opensource.org/licenses/mit-license.php
> >  6
> >  7     """defines genericized SQL types, each represented by a
> > subclass of
> >  8     :class:`~sqlalchemy.types.AbstractType`.  Dialects define
> > further subclasses of these
> >  9     types.
> > 10
> > 11     For more information see the SQLAlchemy documentation on
> > types.
>
> > On Oct 1, 2:48 pm, "Michael Bayer" <mike...@zzzcomputing.com> wrote:
> >> volx wrote:
>
> >>> Here's my program, modified as you suggest. It also creates the  
> >>> table
> >>> so you can try it on any instance of Oracle. No joy on the result.
> >>> Seems like the set_inputsizes isn't called? How can I tell for
> >>> certain?
>
> >>> import sqlalchemy.types as sqltypes
> >>> from exceptions import NotImplementedError
>
> >>> class OracleChar(sqltypes.CHAR):
> >>>     """Patched OracleChar type to fix padding issue
> >>>    http://groups.google.com/group/sqlalchemy/browse_thread/thread/965287
> >>> ...
> >>>     """
> >>>     def get_col_spec(self):
> >>>         return "CHAR(%(length)s)" % {'length' : self.length}
>
> >>>     def get_dbapi_type(self, dbapi):
> >>>         raise NotImplementedError('gotcha')
> >>>         return dbapi.FIXED_CHAR
>
> >> is this using 0.5 or current trunk ?  There's some additional  
> >> restrictions
> >> in trunk on setinputsizes due to some cx_oracle bugs I reported.
> >> Unfortanately my macbook is in the shop so I won't be able to test  
> >> this
> >> myself until possibly next week.   Basically the the  
> >> "set_input_sizes()"
> >> in sqlalchemy/base/default.py should be called for all oracle  
> >> executions
> >> and the datatype on the bind parameter generated by "mycol == <some
> >> value>" should be of your type, i.e. isinstance
> >> ((mycol==5).right.type,
> >> OracleChar).
>
> >>> from sqlalchemy.databases import oracle
> >>> oracle.OracleChar = OracleChar
>
> >>> from sqlalchemy import Table, Column, Integer, MetaData
> >>> from sqlalchemy.databases.oracle import OracleChar
> >>> from sqlalchemy.sql import select, insert
> >>> from sqlalchemy import create_engine
>
> >>> metadata = MetaData()
>
> >>> price_sources = Table('victor_price_sources', metadata,
> >>>     Column('pricesource', Integer, primary_key=True),
> >>>     Column('desciption', OracleChar(100))
> >>> )
>
> >>> dburl = "oracle://user:pas...@servername:1521/dbname"
>
> >>> e = create_engine(dburl, echo=True)
> >>> metadata.bind = e
> >>> metadata.create_all()
> >>> con = e.connect()
>
> >>> ins = price_sources.insert().values(pricesource=1, desciption='EJV')
> >>> con.execute(ins)
>
> >>> s = select([price_sources], price_sources.c.desciption=='EJV')
> >>> all = con.execute(s).fetchall()
> >>> print all
>
> >>> s = select([price_sources])
> >>> all = con.execute(s).fetchall()
> >>> print all
>
> >>> And the results:
>
> >>> In [1]: import sandbox
> >>> 2009-10-01 13:24:25,015 INFO sqlalchemy.engine.base.Engine.0x...9ccc
> >>> SELECT USER FROM DUAL
> >>> 2009-10-01 13:24:25,018 INFO sqlalchemy.engine.base.Engine.0x...9ccc
> >>> {}
> >>> 2009-10-01 13:24:25,022 INFO sqlalchemy.engine.base.Engine.0x...9ccc
> >>> select table_name from all_tables where table_name=:name and
> >>> owner=:schema_name
> >>> 2009-10-01 13:24:25,022 INFO sqlalchemy.engine.base.Engine.0x...9ccc
> >>> {'name': 'VICTOR_PRICE_SOURCES', 'schema_name': 'CDOCOLLAT'}
> >>> 2009-10-01 13:24:25,027 INFO sqlalchemy.engine.base.Engine.0x...9ccc
> >>> CREATE TABLE victor_price_sources (
> >>>         pricesource INTEGER NOT NULL,
> >>>         desciption CHAR(100),
> >>>         PRIMARY KEY (pricesource)
> >>> )
>
> >>> 2009-10-01 13:24:25,027 INFO sqlalchemy.engine.base.Engine.0x...9ccc
> >>> {}
> >>> 2009-10-01 13:24:25,082 INFO
>
> ...
>
> read more »
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalchemy@googlegroups.com
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to