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 -~----------~----~----~----~------~----~------~--~---