Well!  I guess that's exactly why we post sometimes -- the process of
producing the test case bumps the unconscious forward a few steps.  I
quit and did some pleasure reading for a while then came back.  Here's
my own answer that does exactly what I needed it to do.

Add the following property on Itemtype:

@property
def full_heritage(self):


On Nov 25, 12:42 am, Eric Ongerth <[EMAIL PROTECTED]> wrote:
> Unfortunately, I posted the wrong version of my Itemtype class above;
> fortunately it wasn't important for what I was trying to show.  Please
> replace class Itemtype with the following, and note the additional
> test lines and commentary which I also forgot to include.
>
> class Itemtype(object):
>
>     def __repr__(self):
>         return 'Itemtype: %s' % (self.name)
>
>     @property
>     def inherited_features(self):
>         return ([feature for base_itemtype in self.inherits for
> feature in base_itemtype.features])
>
>     @property
>     def features(self):
>         result = self.own_features[:]
>         if self.inherits:
>             result.extend(self.inherited_features[:])
>         return result
>
>     @property
>     def dependent_features(self):
>         return [f for f in self.features if f.determinants]
>
>     @property
>     def independent_features(self):
>         return [f for f in self.features if not f.determinants]
>
> The code i posted the first time was not the right code for the
> inherited_features and features properties on Itemtype.  I must have
> cut and pasted from the wrong test file.
>
> Please observe the following interactions which may help paint a
> clearer picture of what I'm doing with this stuff.
>
> >>>Boot.features
>
> [Footwear Gender, Footwear US Shoe Size, Product Manufacturer, Product
> Model, Product Year, Product Weight]
>
> >>>Boot.dependent_features
>
> [Product Weight]
>
> >>>Boot.independent_features
>
> [Footwear Gender, Footwear US Shoe Size, Product Manufacturer, Product
> Model, Product Year]
>
> >>>Footwear.inherited_features
>
> [Product Manufacturer, Product Model, Product Year, Product Weight]
>
> >>>Footwear.own_features
>
> [Footwear Gender, Footwear US Shoe Size]
>
> These are all examples of some of the useful things I'm using this for
> -- keeping track of which variables ('features'), in an inheriting/
> cascading type system, are dependent and which ones are independent.
> Later, when values are entered and stored for each feature, the
> relationships between the values will be constrained by these same
> feature dependency links, without having to repeat them at that time.
>
> Sorry for the wrong code before.  Oh yeah, I forgot to demonstrate
> this too, but it's trivial:
>
> >>>Model = session.query(Feature).filter_by(name='Model').one()
> >>>Model.dependents
> [Product weight]
> >>>Gender.dependents
>
> [Product weight]
>
> ... so all this works the other way around too, though requesting the
> dependents of a given feature is not as interesting as requesting a
> given feature's determinants.
>
> Eric
>
> On Nov 24, 11:51 pm, Eric Ongerth <[EMAIL PROTECTED]> wrote:
>
> > Below, I have attached a working testcase.  It works, yes -- but my
> > question is that I need to make an improved version of a particular
> > method on one of my classes.  The following model will probably
> > explain itself for the most part.  I'll let you read it first, then
> > offer a few explanatory notes afterward just in case.  Finally, at the
> > end, I will describe the difference between what the method in
> > question does now, and what I would like it to do.
>
> > The nature of the response I am seeking is: a description of what I
> > need to do to build a better version of the method I'm speaking of,
> > including any further insight on the practice of joining at multiple
> > levels of a recursive / self-referential (but loop-free) graph.
>
> > ---snip---
>
> > from sqlalchemy import *
> > from sqlalchemy.sql import *
> > from sqlalchemy.orm import *
>
> > engine = create_engine('sqlite://')
>
> > metadata = MetaData(bind=engine)
>
> > itemtypes = Table('itemtypes', metadata,
> >     Column('name', Text, primary_key=True))
>
> > itemtype_inheritance = Table('itemtype_inheritance', metadata,
> >     Column('itemtype_name', Text, ForeignKey('itemtypes.name'),
> > primary_key=True),
> >     Column('parent_name', Text, ForeignKey('itemtypes.name'),
> > primary_key=True))
>
> > features = Table('features', metadata,
> >     Column('id', Integer, primary_key=True),
> >     Column('name', Text),
> >     Column('root_itemtype_name', Text, ForeignKey('itemtypes.name')))
>
> > feature_dependencies = Table('feature_dependencies', metadata,
> >     Column('dependent_id', Integer, ForeignKey('features.id'),
> > primary_key=True),
> >     Column('determinant_id', Integer, ForeignKey('features.id'),
> > primary_key=True))
>
> > metadata.drop_all()
> > metadata.create_all()
>
> > itemtypes.insert().execute([
> >     {'name': 'Product'},
> >     {'name': 'Footwear'},
> >     {'name': 'Boot'},
> >     {'name': 'Ski'}
> > ])
>
> > itemtype_inheritance.insert().execute([
> >     {'itemtype_name': 'Footwear', 'parent_name': 'Product'},
> >     {'itemtype_name': 'Boot', 'parent_name': 'Footwear'},
> >     {'itemtype_name': 'Ski', 'parent_name': 'Product'}
> > ])
>
> > features.insert().execute([
> >     {'id': 1, 'name': 'Manufacturer',
> > 'root_itemtype_name':'Product' },
> >     {'id': 2, 'name': 'Model', 'root_itemtype_name':'Product' },
> >     {'id': 3, 'name': 'Year', 'root_itemtype_name':'Product' },
> >     {'id': 4, 'name': 'Gender', 'root_itemtype_name':'Footwear' },
> >     {'id': 5, 'name': 'US Shoe Size',
> > 'root_itemtype_name':'Footwear' },
> >     {'id': 6, 'name': 'Length', 'root_itemtype_name':'Ski' },
> >     {'id': 7, 'name': 'Weight', 'root_itemtype_name':'Product' }
>
> > ])
>
> > feature_dependencies.insert().execute([
> >     {'dependent_id': 7, 'determinant_id': 1},
> >     {'dependent_id': 7, 'determinant_id': 2},
> >     {'dependent_id': 7, 'determinant_id': 3},
> >     {'dependent_id': 7, 'determinant_id': 4},
> >     {'dependent_id': 7, 'determinant_id': 5},
> >     {'dependent_id': 7, 'determinant_id': 6}
> > ])
>
> > class Itemtype(object):
>
> >     def __repr__(self):
> >         return 'Itemtype: %s' % (self.name)
>
> >     @property
> >     def inherited_features(self):
> >         return reduce(list.extend,
> >                       [base_itemtype.features for base_itemtype in
> > self.inherits],
> >                       [])
>
> >     @property
> >     def features(self):
> >         return self.own_features.extend(self.inherited_features)
>
> >     @property
> >     def dependent_features(self):
> >         return [f for f in self.features if f.determinants]
>
> >     @property
> >     def independent_features(self):
> >         return [f for f in self.features if not f.determinants]
>
> > class Feature(object):
>
> >     def __repr__(self):
> >         return '%s %s' % (self.root_itemtype_name, self.name)
>
> >     def determinants_in_scope_of(self, itemtype):
> >         return (session.query(Feature)
> >                 .join(FeatureDependency.determinant)
> >                 .join(Feature.root_itemtype)
> >                 .filter(and_(FeatureDependency.dependent_id==self.id,
> >                              Itemtype.name==itemtype.name))).all()
>
> > class FeatureDependency(object):
>
> >     def __repr__(self):
> >         return "F_D: %s depends on %s" % (self.dependent.name,
> >                                           self.determinant.name)
>
> > mapper(Itemtype, itemtypes, properties={
> >     'inherits':relation(Itemtype,
> >         secondary=itemtype_inheritance,
> >         primaryjoin=
> > (itemtypes.c.name==itemtype_inheritance.c.itemtype_name),
> >         secondaryjoin=
> > (itemtype_inheritance.c.parent_name==itemtypes.c.name),
> >         backref='progeny'),
> >     'own_features':relation(Feature,
> >         primaryjoin=(features.c.root_itemtype_name==itemtypes.c.name),
> >         backref=backref('root_itemtype', uselist=False))
> >     })
>
> > mapper(Feature, features, properties={
> >     'dependents':relation(Feature,
> >         secondary=feature_dependencies,
> >         primaryjoin=
> > (feature_dependencies.c.determinant_id==features.c.id),
> >         secondaryjoin=
> > (feature_dependencies.c.dependent_id==features.c.id),
> >         backref=backref('determinants'))
> >     })
>
> > mapper(FeatureDependency, feature_dependencies, properties={
> >     'dependent':relation(Feature,
> >         uselist=False,
> >         primaryjoin=
> > (feature_dependencies.c.dependent_id==features.c.id),
> >         backref='feature_dependencies_as_dependent'),
> >     'determinant':relation(Feature,
> >         uselist=False,
> >         primaryjoin=
> > (feature_dependencies.c.determinant_id==features.c.id),
> >         backref='feature_dependencies_as_determinant')
> >     })
>
> > Session = sessionmaker(bind=engine)
> > session = Session()
>
> > Product = session.query(Itemtype).filter_by(name='Product').one()
> > Ski = session.query(Itemtype).filter_by(name='Ski').one()
> > Footwear = session.query(Itemtype).filter_by(name='Footwear').one()
> > Boot = session.query(Itemtype).filter_by(name='Boot').one()
> > Weight = session.query(Feature).filter_by(name='Weight').one()
> > Gender = session.query(Feature).filter_by(name='Gender').one()
> > Year = session.query(Feature).filter_by(name='Year').one()
>
> > ---snip---
>
> > (to anyone who wants to play with this and doesn't know how, save the
> > above code as testcase.py, and then run it from shell with python -i
> > testcase.py; you then have a Python interpreter with all of the above
> > objects still active, including the sqlalchemy session, with the
> > ability to query and experiment).
>
> > Notes on what this is supposed to model: Here are some of the facts in
> > the problem domain.
>
> > Each Itemtype inherits from others above it, except for root itemtypes
> > (the only one of which in this example is Product).  The reason for
> > using an inheritance paradigm here is so that you can set Features on
> > any Itemtype and have them inherited by all of the subcategories (sub-
> > Itemtypes) of that Itemtype.  In other words, once you give the
> > itemtype
>
> ...
>
> read more »
--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---

Reply via email to