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