Great, thanks for replying.

His "generic schema" approach is essentially what I'm already doing
for other more complex parts of my model.
http://www.agiledata.org/essays/mappingObjects.html#MapToGenericStructure

On just this Companies-Vendors-Manufacturers part, I was hoping to get
away with something simpler.  So the spirit of my question was "help
me make sure I'm not overlooking a simple easy way that SA's joined
inheritance already handles what I want."  I just didn't want to miss
anything.  As it stands, I guess I'll just have to wire up whatever I
need and see how it goes.

-----
There ends my question, the following is just shared thought:
-----

I'm pretty excited about the generic schema approach, of which the
link above describes the basic essentials.  For better or for worse, I
reinvented it from scratch, being unaware of most related/relevant
literature when I first was working on this stuff in 2008.  SqlAlchemy
has made it amazingly easy to implement.

I have Products that come in various Subproducts (for instance a model
of shoe is the abstract Product, but you can't buy the product itself;
you can buy it as a subproduct: e.g., Size 10 of that shoe, in a
specific color).

Each product references one or more product types (here's one of the
points where there is multiple inheritance going on).  The product
type does not carry information itself, it's a key to one or more
attribute groups.

When creating a Product, I specify one or more product types, which
thereby pulls in one or more attribute groups, ultimately generating a
resultant set of attributes that the product expects to have.  In the
basic view of this, the attributes are not given values at the Product
level.  The creation of a Subproduct is where all of the product's
attributes are associated with specific scalar values.  This is all
done through a type system where I can create collection-based or
numeric (or other) types and their associated validators on the fly
(during runtime) and connect them to attributes.

In a more advanced view, necessary in order to really model actual
commercial product domains, it is necessary for some attributes to be
assigned values at the Product level.  The attributes themselves carry
flags that declare whether they are to be assigned values at the
eventual subproduct instantiation (the default), or be held and
assigned at the product level instead.

Then to further match the model to what's really going on in the
domain being modeled, it happens that we need to be able to create a
product type structure that works for 90-95%ish of the products that
will use it, and the remaining 5-10% will simply suppress or override
some of the attributes.  An attribute can be suppressed altogether, or
the default declaration of whether that attribute should be assigned a
value at the product vs. the subproduct level can be overridden on a
per-product basis.

Additionally, product types are allowed to multiply inherit from each
other, thus we get a directed (and I do some processing to make sure
it stays acyclic) graph of product type inheritance.  Beginning from
just a single identifier of a product or subproduct, determining
exactly which attribute-value pairs (facts, essentially) are attached
to it requires looking all the way up the product type inheritance
chain/graph.  This would be a lot more painful without SqlAlchemy and
i am endlessly thankful for all of the loading and associating
machinery we're so lucky to have here.

This all could begin to sound terribly inefficient, and yes, I'm not
planning to scale it to too many millions of products!  But I'm
optimistic that with appropriate view creation and good indexing and
caching I can keep it reasonably performant.  In fact, once a product
or subproduct is created in this system, I'm interested in creating
some sort of frozen view of that item that is able to be loaded extra
quickly without too much join activity.  That sounds appropriate
because, for example, a product will not change its weight often (in
fact only when incorrect data is corrected later, or something).
Attributes like price will change more often, but I can afford to have
writes rather slow as long as reads are quick, so I think that might
not be too hard to handle.

This is the foundation of a future inventory and point-of-sale
application which aims to provide a lot of improvements over currently
available software by starting with far better modeling of the actual
product data.  Most systems out there in production just use a big
spreadsheet-like database with lots of irrelevant columns, and columns
that have a different meaning depending on what type of row you're
looking at, and many of these systems don't even have a system to deal
with that, they just expect you to be ok with thinking "Attr1 is color
if I'm looking up an article of one type, but it's size if I'm looking
up another, or it might hold something else entirely."

There's a zope-based alternative that is the closest I've found thus
far to doing what I'm trying to do, but they went down the road of
delving into Python class mechanics to force all of this to happen via
Python classes and instances, rather than just keeping it all
relational.  I'm trying to build this with a relational perspective
through and through.  So far the only drawback is the complexity of
assembling views of products and items, and of comparing disparate
kinds of them; but I actually look forward to that as I believe a
number of unforeseen benefits are going to accrue from simply modeling
powerfully yet flexibly from the beginning.

Cheers,
Eric

On Nov 21, 3:38 pm, Michael Bayer <mike...@zzzcomputing.com> wrote:
> On Nov 21, 2010, at 4:41 PM, Eric Ongerth wrote:
>
> > I must be in a "search blind spot", I'm having trouble finding
> > references and examples for this pattern, though I feel certain I've
> > seen examples around the sqlalchemy literature a couple of times
> > before.
>
> > I have a table of Companies, and then further tables of Manufacturer
> > and Vendor info which apply to some companies.  So a company can be
> > stored just as a company, or as a company that happens to be a
> > manufacturer, and/or happens to be a vendor.  I don't want the
> > manufacturer and vendor designations to be exclusive of each other; it
> > should be possible for a company to be both.
>
> The thing I pointed someone to the other day regarding multiple inheritance 
> in general is 
> athttp://www.agiledata.org/essays/mappingObjects.html#MappingMultipleIn....   
> My general attitude about that example is "yeah great, go nuts !".   i.e. if 
> someone wants to get into it, great, good luck, but I haven't personally ever 
> had any situation that called for something that complex and if I did, I'd 
> probably try to get around it somehow.   Maybe someday I'll actually need the 
> feature though, then I'll figure out how to do it generically, then it will 
> be the next big SQLA feature everyone needs, who knows.
>
>
>
> > I thought of just having a boolean field on the Company table for each
> > 'child' type.  So (company.manufacturer == True) would tell me it's
> > safe to write to or read from attributes whose storage is in the
> > manufacturer info table.  Likewise, (company.vendor == True) would
> > indicate that it's safe to write to or read from attributes whose
> > storage is in the vendor info table.  And of course some companies
> > will be filed as neither, so I won't attempt to access mfr or vendor
> > info about them.
>
> so I think if you are trying to get multiple tables to compose into a single 
> type, its likely very possible using a combination of relationship() and 
> association_proxy().  relationship() to maintain the linkages to other 
> tables, association_proxy or something similar (perhaps like the hybrid 
> example, after all we are just using Python attribute tricks) to create a 
> one-level-of-names type of facade.
>
>
>
> > Regular SA joined-table inheritance doesn't work this way since it
> > requires a discriminator column taking a single value at a time.
> > Still I would love to use joined-table inheritance if I could.  Is
> > there a way?
>
> joined inheritance might be involved, but in a practical sense you have to 
> think about what your SELECT queries are going to look like if locating a 
> record requires spanning across three or four tables.

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.

Reply via email to