I had in mind that the metaclass approach would be used, but not  
necesarily with the "walking" stuff going on.

if you really want to think about this, the idea for a types overhaul  
is ticket #526.  that breaks up the "DDL" from the "adaptation" side  
of things.  a metaclass approach would be at the base of it  
controlling a registry of information about types.


On Aug 15, 2007, at 12:15 PM, [EMAIL PROTECTED] wrote:

>
> On Tuesday 14 August 2007 23:05:44 Michael Bayer wrote:
>> On Aug 14, 2007, at 3:30 PM, [EMAIL PROTECTED] wrote:
>>> databases/sqlite: (reflecttable)
>>>   pragma_names is missing the BOOLEAN word/type -> nulltype
>>>
>>> btw why isn't each dialect-typeclass adding it's own entry to
>>> that pragma_names, respectively to the colspecs ?
>>> Or, each class to have those pragmaword and basetype, and the
>>> dicts to be made by walking locals() if issubclass(..) ?
>>>
>>> Anyway, these dicts (the "grammar") should be automaticaly built
>>> from available typeclasses...
>>
>> patches welcome....
>>
>>
> here 2 versions.
> One is simple, walking the module.namespace for
> issubclass(TypeEngine), expecting to find .pragma and .colspec in
> that class and collects them. The .colspec can probably be figured
> out from __bases__ (as in other version)
>
> <pre>
> def _issubclass( obj, klas):
>     'fail/fool-proof issubclass() - works with ANY argument'
>     from types import ClassType
>     return isinstance(obj,(type,ClassType)) and issubclass(obj,klas)
>
> def collect_colspecs( namespace):     #this can be moved out of here
>     colspecs = {}
>     pragma_names = {}
>     for obj in namespace.itervalues():
>         if _issubclass( kl, sqlalchemy.TypeEngine):
>             c = getattr( kl, 'colspec', None) #or 'basetype'
>             p = getattr( kl, 'pragma', None)  #or 'sqltype' or rawtype
>             if c and p:
>                 colspec[c]=kl
>                 pragma_names[c]=kl
>     return colspecs, pragma_names
>
> class SLNumeric(sqltypes.Numeric):
>     colspec,pragma = sqltypes.Numeric, 'NUMERIC'
>     def get_col_spec(self):
>         if self.precision is None:
>             return "NUMERIC"
>         else:
>             return "NUMERIC(%(precision)s, %(length)s)"%self.__dict__
>
> class SLInteger(sqltypes.Integer):
>     colspec,pragma = sqltypes.Integer, 'INTEGER'
>     def get_col_spec(self): return self.pragma
> ...
> colspecs, pragma_names = collect_colspecs( locals() )
>
> </pre>
>
> ========================
>
> the other one uses metaclass, and .pragma is set up, and guesses
> colspec's abstract_type from __bases.
>
> <pre>
> class MetaDialectType( type): #this can be moved out of here
>     def __new__( metacls, name, bases, dict_):
>         #find top-most abstract_type base
>         abstract_type = None
>         for b in bases:
>             #XXX is walk in depth needed?
>             #e.g. if allowed class SLInt2( SLInteger):...
>             if issubclass( b, sqltypes.TypeEngine):
>                 abstract_type = b
>                 break
>         assert abstract_type, 'class %s: cannot find any abstract \
>             base type; do inherit from some sqlalchemy type' % name
>
>         try:
>             pragma = dict_['pragma']
>         except KeyError:
>             assert 0, 'class %s: cannot find any pragma' % name
>
>         klas = type.__new__( metacls, name, bases, dict_)
>         metacls.colspecs[ abstract_type] = klas
>         metacls.pragma_names[ pragma]=klas
>         return klas
>
> class SLMetaDialectType( MetaDialectType):
>     colspecs = {}
>     pragma_names = {}
>
> class SLNumeric( sqltypes.Numeric):
>     __metaclass__ = SLMetaDialectType
>     pragma = 'NUMERIC'
>     def get_col_spec(self):
>         r = self.pragma
>         if self.precision is not None:
>             r += "(%(precision)s, %(length)s)" % self.__dict__
>         return r
>
> class SLInteger( sqltypes.Integer):
>     __metaclass__ = SLMetaDialectType
>     pragma = 'INTEGER'
>     def get_col_spec(self): return self.pragma
>
> ...
> colspecs = SLMetaDialectType.colspecs
> pragma_names = SLMetaDialectType.pragma_names
> </pre>
>
> ==========
> There are 2 choices to make:
>  - walk locals() vs using metaclass
>  - whether to touch get_col_spec()s
>
> i wanted to have everything specified only once.
> Therefore the get_col_spec() redefinition.
> It can be:
>  1 left as is, just adding a separate .pragma (no gain,
> consistency-wise, e.g. VARCHR in one place and VARCHAR in another)
>  2 remade to use the self.pragma where equivalent (like 80% of
> places) - a lot of same code repeated
>  3 put a default one in some base class for all dialect-types, e.g.
> DialectBaseType, which can be then used for filtering locals() or to
> bring metaclass
>  4 created in the metaclass unless explicitly specified - this is most
> obscure.
>
> btw i suggest some namechanges, colspec -> abstract_type and
> pragma_name -> rawdb_type; or something alike.
>
> ciao
> svil
>
> >


--~--~---------~--~----~------------~-------~--~----~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to