def __init__(cls, cl_name, bases, namespace): # add a dictionary to store projections for this class. cls._projections = {} # tablename guessing if namespace.get("table") is not None: # table has been explicitly declared, so # turn off guess_tablename for subclasses if not namespace.has_key("guess_tablename"): cls.guess_tablename = False elif cls.guess_tablename: # leave guess_tablename for subclasses cls.table = cl_name.lower() # sequence mapping sequence_mapper = namespace.get("sequence_mapper") if isfunction(sequence_mapper): cls.sequence_mapper = staticmethod(sequence_mapper) else: cls.sequence_mapper = sequence_mapper # field guessing if namespace.get("guess_columns", False): if cls.guesscache == True: # supply default cache cls.guesscache = GuessCache() elif isinstance(cls.guesscache, basestring): # assume it is a path cls.guesscache = GuessCache(cls.guesscache) if "fields" in namespace or "unique" in namespace: raise ValueError, ( "incompatible declarations: guess_columns " "with explicit declaration of fields and/or unique" ) gfields, gunique = cls._getTableDescription() namespace["fields"] = gfields.values() namespace["unique"] = gunique # create Field objects declared locally in this class # and store them in a temporary dict fielddict = {} # we keep track of which fields are declared just with a string; # inheritance semantics are a little different for these simplefields = set() for f in namespace.get("fields", ()): # support for tuple syntax for plain Jane fields. if isinstance(f, basestring): m = _as_pat.match(f) if m: name = m.group(1) asname = m.group(2) simplefields.add(asname) f = cls._create_field(name=name, asname=asname) else: simplefields.add(f) f = cls._create_field(f) elif isinstance(f, dict): f = cls._create_field(**f) elif isinstance(f, (tuple, list)): f = cls._create_field(*f) elif not isinstance(f, Field): raise ValueError, "cannot coerce into a field: %s" % f # add to field container fielddict[f.asname] = f # handle inheritance of fields and unique declarations. # skipping object and dict is a trivial optimization, # because we know those classes won't be relevant revbases = [x for x in bases[::-1] if x not in (object, dict)] cls._fields = {} uniqueset = set() for b in revbases: flds = getattr(b, "_fields", None) if flds: if cls._is_projection: flds = _restrict(fielddict, flds) cls._fields.update(flds) uniq = getattr(b, "unique", None) if uniq: # transform into a set of sets. This way, # multi-column unique constraints are # unordered. uniq = set(_setize(x) for x in uniq) if cls._is_projection: uniq = _restrict(fielddict, uniq) uniqueset.update(uniq) # If a field is declared upstream and you redeclare it in a # subclass as a simple field (just a fieldname), then the # previous field definition is inherited; otherwise, the # subclass's definition wins. This is useful for projections. updatefields = ((x, y) for x, y in fielddict.iteritems() if not (x in cls._fields and x in simplefields)) cls._fields.update(updatefields) uniqueset.update(_setize(x) for x in namespace.get("unique", ())) # We now have all the inherited declarations, and figure out # sequences and additional unique constraints. cls._sequenced = {} for f in cls._fields.itervalues(): if f.sequence: cls._sequenced[f.asname] = f.sequence if f.unique: uniqueset.add(frozenset((f.asname,))) cls._unique = frozenset(uniqueset) # add attribute access to fields if cls.use_attributes: for name in cls._fields: if not hasattr(cls, name): # a field is also a descriptor setattr(cls, name, cls._fields[name])
def __init__(cls, cl_name, bases, namespace): # add a dictionary to store projections for this class. cls._projections = {} # tablename guessing if namespace.get('table') is not None: # table has been explicitly declared, so # turn off guess_tablename for subclasses if not namespace.has_key('guess_tablename'): cls.guess_tablename = False elif cls.guess_tablename: # leave guess_tablename for subclasses cls.table = cl_name.lower() # sequence mapping sequence_mapper = namespace.get("sequence_mapper") if isfunction(sequence_mapper): cls.sequence_mapper = staticmethod(sequence_mapper) else: cls.sequence_mapper = sequence_mapper # field guessing if namespace.get('guess_columns', False): if cls.guesscache == True: # supply default cache cls.guesscache = GuessCache() elif isinstance(cls.guesscache, basestring): # assume it is a path cls.guesscache = GuessCache(cls.guesscache) if 'fields' in namespace or 'unique' in namespace: raise ValueError, ( "incompatible declarations: guess_columns " "with explicit declaration of fields and/or unique") gfields, gunique = cls._getTableDescription() namespace['fields'] = gfields.values() namespace['unique'] = gunique # create Field objects declared locally in this class # and store them in a temporary dict fielddict = {} # we keep track of which fields are declared just with a string; # inheritance semantics are a little different for these simplefields = set() for f in namespace.get('fields', ()): # support for tuple syntax for plain Jane fields. if isinstance(f, basestring): simplefields.add(f) f = cls._create_field(f) elif isinstance(f, dict): f = cls._create_field(**f) elif isinstance(f, (tuple, list)): f = cls._create_field(*f) elif not isinstance(f, Field): raise ValueError, "cannot coerce into a field: %s" % f # add to field container fielddict[f.name] = f # handle inheritance of fields and unique declarations. # skipping object and dict is a trivial optimization, # because we know those classes won't be relevant revbases = [x for x in bases[::-1] if x not in (object, dict)] cls._fields = {} uniqueset = set() for b in revbases: flds = getattr(b, '_fields', None) if flds: if cls._is_projection: flds = _restrict(fielddict, flds) cls._fields.update(flds) uniq = getattr(b, 'unique', None) if uniq: # transform into a set of sets. This way, # multi-column unique constraints are # unordered. uniq = set(_setize(x) for x in uniq) if cls._is_projection: uniq = _restrict(fielddict, uniq) uniqueset.update(uniq) # If a field is declared upstream and you redeclare it in a # subclass as a simple field (just a fieldname), then the # previous field definition is inherited; otherwise, the # subclass's definition wins. This is useful for projections. updatefields=((x, y) for x, y in fielddict.iteritems() \ if not (x in cls._fields and x in simplefields)) cls._fields.update(updatefields) uniqueset.update(_setize(x) for x in namespace.get('unique', ())) # We now have all the inherited declarations, and figure out # sequences and additional unique constraints. cls._sequenced = {} for f in cls._fields.itervalues(): if f.sequence: cls._sequenced[f.name] = f.sequence if f.unique: uniqueset.add(frozenset((f.name, ))) cls._unique = frozenset(uniqueset) # add attribute access to fields if cls.use_attributes: for name in cls._fields: if not hasattr(cls, name): # a field is also a descriptor setattr(cls, name, cls._fields[name])