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