volx wrote:
>
> All has been working fine in 0.6, Mike. Thanks.
>
> Out of curiosity how do you unit test against Oracle. Do you use some
> kind of mock object?

the test suite has --db and --dburi options that allow any URI to be used
for tests.   i.e. nosetests --dburi oracle://scott:ti...@localhost/xe .   
The tests are sensitive to the backend in use so many oracle-specific
tests get invoked with that URL.




>
> On Oct 4, 10:01 am, Michael Bayer <mike...@zzzcomputing.com> wrote:
>> On Oct 3, 2009, at 5:18 PM, volx wrote:
>>
>>
>>
>> > 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?
>>
>> that's correct and that is the usage contract of all versions of  
>> SQLAlchemy.   in 0.6 we just made it very clear.   the exception  
>> though is when the DB-specific type accepts additional arguments, like  
>> the MySQL types - but again we removed the need to deal with special  
>> names like MSString and such -  if you wanted a MySQL-specific  
>> VARCHAR, you'd import VARCHAR from the MySQL dialect and utilitize its  
>> special constructor arguments.
>>
>>
>>
>> > 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.
>>
>> its likely not a big fix in 0.5 but Oracle support really began most  
>> fully in 0.6, where for example we got 100% unit test coverage.
>>
>>
>>
>> > 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
>>
>> ...
>>
>> 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