> > does the metaclass create a mapper() for every subclass ? i.e. is > there a mapper for Server, SunServer, etc ? it seems like there is > (since by "the wrong mapper" i meant, calling object_mapper(instance) > returns a Server or SunServer mapper, not the Thing mapper which > loaded the object). >
Yes the metaclass makes a mapper for for each subclass. The Thing class gets mapped to the thing table while the subclasses get mapped to a select() based on their meta_attrs. I used the assign_mapper so that someone could just do a Server.select() and get all Things that could be managed by that driver. If all the classes ultimately mapped to the same table, what are the implications of using the wrong mapper? I didn't run into any behavior that wasn't what I desired. > if there is a distinct mapper per class, cant your metaclass simply > assign a hidden "type" attribute to each class, a single string value > which indicates what class to load ? then you can just have a single > "type" column in the thing table and SA's regular inheritance > mechanisms take care of the rest. the metaclass would only need to > worry about things when the user first creates the object. im not > seeing any reasons here why this wouldnt work. > So, originally, I did have a 'type' column and chose my class based on that, but I wanted something more flexible. So the use case I'm trying to cover is if say, my v0.1 code has a Server() class. People use it happily and do things like: s1 = Server('server1') s1.addAttr('model', 'sun') flush() s2 = Server('server2') s2.addAttr('model', 'apple') flush() etc... So v0.1 users fill their DBs with all sorts of data. In v0.2 I want to add an AppleServer class that subclasses Server. It will add killer features like AppleServer.beShiny() and AppleServer.commandN(). In the scheme with a type column only _new_ instances of AppleServer would have the correct 'appleserver' value in the type column. But I want AppleServer to work with _any_ server that also has a ('model', 'apple') attribute. So I would have to do an update to the database and alter the values throughout the DB. In a way you're also making anything with type=='appleserver' NOT a Server because all Servers have type=='server'. So in terms of object orientation an AppleServer is a Server, but in terms of the datastore an 'appleserver' is not a 'server'. (though that's possibly merely an academic quibble). > also when you say "the user shouldnt have to know about SA", that > suggests the other way I might do this, that Thing stays as Thing and > the user-facing object is actually a wrapper for a Thing, and is not > mapped to the ORM directly. this makes it less convenient as the > user-facing object cant be used in SA operations directly, you'd have > to translate around sessions and queries. Yeah, I've avoided this path where I can because, well, SA is pretty cool and if a developer can make use of it then I definitely want them to have the option. But I don't want to _require_ them to use SA to add functionality to the app. > > theres three examples in the distro you should look at: > > examples/polymorph/single.py - single table inheritance > examples/vertical/vertical.py - stores "vertical" attributes > similarly to your Thing > examples/elementtree/adjacency_list.py - this is mostly about self- > referential relationships, but also illustrates how a non-mapped > object can be "supplied" its internals by a mapped object (i.e. its a > wrapper). I'm still soaking in these examples. I think what I really want is to have mapper accept something like polymorphic_func and base_class. So I would pass it my _setProperClass function and Thing. The mapper will build against Thing and then run _setProperClass against the instance. Yeah, I'm cheating, cause that's kind of basically what I'm doing now. I'm just not sure how else to achieve the functionality I'm looking for. Another slightly different scheme, might be to have every object be a Thing, but dynamically add MixIns depending on the attributes the Thing had. But even in that case, I'd need to be able to call a _setupMixins function post-population of the instance. Perhaps the mapper is treating the class as more sacred than I am. My _setProperClass script is switching out the class of an object. That's pretty dramatic and this is the first time I've ever done anything like that. I'm only doing it to change an object's namespace and thus give it new functionality. I tried it cause, well, python lets me, and it worked much better than I expected. I'm definitely taking advantage of an implementation detail of python classes. There might be a better way, but I'm still not satisfied with the alternatives I've seen and this seemed pretty cool. -Ron --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---