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 [email protected]
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
-~----------~----~----~----~------~----~------~--~---