On Jan 3, 2011, at 2:02 AM, Eric Ongerth wrote: > So I tried my solution of deleting and then re-adding each object > (row) in question. Didn't work quite like that; instead I had to > delete, make_transient(), and then re-add. Still didn't quite work; > for rows that had sa relationships via FKs to other tables, in order > to avoid errors I had to give the objects thus related a similar > treatment, calling make_transient() and then re-associating them. > > Lo and behold, for tables that fit that description it worked and the > discriminator is set properly now. But for the rest of the tables, > those which did not have relationships that needed taking care of in > that way to avoid errors, their rows still aren't getting the > discriminator set. I tried using "instance_state(obj).modified = > True" on them before flush, but that didn't help either. Still > haven't found a solution for the rest of those. > > I don't mean to annoy you in persisting with this approach when it's > not to your liking. It's just that at this point I'm trying to work > it all the way through in this manner just to come to a better > understanding of the ORM's workings.
You can't set the discriminator column in 0.6 with the ORM. The mapper will ignore it. You need to forego the ORM or use 0.7. > > > On Jan 2, 9:55 pm, Eric Ongerth <ericonge...@gmail.com> wrote: >> Ah! I did it again. You may or may not remember I asked you a >> different question yielding the same answer a couple of months ago! >> I've got to put a stop to that trend. >> >> To quote from your blog post: >> >> === >> In fact, while this table scheme is exactly joined table inheritance, >> and we could certainly go the "straight" route of creating an >> Addressable base class and mapper from which the User and Order >> classes/mappers derive, then creating the traditional SA "polymorphic >> mapping" using UNION ALL (or whatever surprise 0.4 has in store) with >> a relationship to Address, here we're going to do it differently. >> Namely, because we are still going to look at this association as a >> "cross-cutting concern" rather than an "is-a" relationship, and also >> because SA's explicit inheritance features only support single >> inheritance, and we'd rather not occupy the "inherits" slot with a >> relationship that is at best a mixin, not an "is-a". >> === >> >> I actually started modeling this exactly the way you're suggesting in >> that post. I added a "trackable_id" column to each of the six tables, >> as a foreign key to a table of association objects. But then I >> reasoned as follows: (1) great, now I have two unique ID columns in >> each of these tables and that's almost never a good thing. (2) great, >> now I'm going to have to add more program logic to explicitly create >> an association object every time I add a row to any of these tables. >> Clunky. >> >> Your blog post shows how to fix problem (2) there with some very cool >> python magic. Ok, it's not even magic, it's clear enough. But as >> I've noticed before, I still haven't absorbed your level of comfort >> with throwing that stuff around. I understand it well enough, but >> when I see underscores I start thinking "can't this be done another >> way without wizardry"? >> >> I suppose even that point is moot when I recognize that my solution >> using inheritance actually calls upon a lot of very clever programming >> within the guts of sqlalchemy. >> >> Your most salient point of all, for me, is where you note that that >> there's currently only one "slot" for inheritance and there isn't a >> very strong case for occupying it with a cross-cutting concern that is >> "at best a mix-in, not an 'is-a'. " >> >> So now I'm curious, have you given much thought to advancing the >> possibility of supporting multiple inheritance with SA's explicit >> inheritance features? Or is that just too dangerous (or just too much >> of a pain to work out). Or too tempting for people to brew up all >> manner of ridiculous and unnecessary schema with it. >> >> Thank you for your thoughts. >> >> On Jan 2, 9:18 pm, Michael Bayer <mike...@zzzcomputing.com> wrote: >> >>> On Jan 2, 2011, at 11:25 PM, Eric Ongerth wrote: >> >>>> On Jan 2, 7:59 am, Michael Bayer <mike...@zzzcomputing.com> wrote: >>>>> Curious here is what kind of scheme you have that requires a manual >>>>> setting of the discriminator. >> >>>> Forgive me, I tried to indicate that it doesn't, this is just a one- >>>> time thing I have to do to get this database fixed up. Here's the >>>> whole story in a nutshell. I had six tables (person, company, >>>> product, item, etc.) that had little to do with each other. >>>> Eventually I decided that the objects symbolized by the rows in those >>>> tables had a cross-cutting concern: I want to be able to attach action >>>> tickets (sort of like in Trac) and notes to them. The project I'm >>>> working on has a certain limited amount of CRM/ERP type stuff as part >>>> of its scope, thus tickets, notes, and so on. >> >>>> So where these tables originally each had their own unique primary key >>>> "id" columns, I realized that in order to be able to affix notes >>>> equally to a person, a company, a product, etc., I wanted to have all >>>> of these disparate tables pull their IDs from a common table holding a >>>> single column, a column of "trackable object IDs". Sort of like the >>>> POID concept used for certain concerns >>>> inhttp://www.agiledata.org/essays/mappingObjects.html. >> >>>> Seemed to me a simple way to make that work, without having to build a >>>> bunch of ungainly trigger machinery, is make all of these tables >>>> inherit from that common ID table; thus a joined table inheritance >>>> setup. I successfully scripted all of the changes necessary so that >>>> instead of their old ID columns, each table's ID column now is still >>>> its primary key but is also a foreign key to the common ID table. >> >>> oh. OK no, I wouldn't use "joined inheritance" for a "cross-cutting" >>> concern. This is the polymorphic association pattern, which from a >>> database table perspective, looks the same in fact. But the "cross >>> cutting" concern is modeled at the ORM level via relationship. The blog >>> post is extremely old at this point but it should get the idea across: >>> http://techspot.zzzeek.org/2007/05/29/polymorphic-associations-with-s... >> >>> Also if the question about "using the ORM or not" refers to just the >>> activity of migrating the data to the new structure, I'd possibly skip the >>> ORM for a migration, since its a single operation that has to work only >>> once. It sort of depends on what seems more straightforward and also the >>> number of rows in play (if it were millions, the migration might need to be >>> composed entirely as SQL statements without any need to load into memory, >>> for example). >> >>>> At that point I had sort of "Frankensteined" a joined-table >>>> inheritance situation... I had managed to do all of the constraint >>>> dropping and adding that was needed, I managed to keep all of the rows >>>> in most of the tables (only had to rebuild some of them), and >>>> everything was peachy. Now a given ID of any row within any of these >>>> six tables, is unique over all six of the tables. Thus notes, >>>> tickets, whatever other cross-cutting deals, can be attached to such >>>> unique IDs or groups thereof. >> >>>> The only remaining problem was that the parent table actually needs >>>> more than just the ID column. It needs the discriminator column if >>>> I'm going to really handle this as joined-table inheritance. >>>> Everything else is in place except the discriminator column is not set >>>> for any of my existing rows that made it through this refactoring. >>>> The new setup works perfectly for newly added people, companies, >>>> items, products, etc... the ID is assigned and inherited, the >>>> discriminator is assigned. (Of course.) But I need a way to get in >>>> there and set the discriminator column for my _existing_ rows that >>>> came through from before. >> >>>> I suppose I could just go with Concrete Table inheritance, but the >>>> added difficulties with relationships are less enticing. Intuitively >>>> the joined table idea seems to fit. >> >>>> Should I just take a deep breath and get this done without the ORM? I >>>> appreciate your answer regarding pre-0.7 vs. 0.7 approaches, that's >>>> the sort of stuff I was looking for when I went ahead and asked this >>>> question rather than quietly working around it. >> >>>> Your answer also just jogged my brain in a way that I failed to do >>>> last night. I could just delete and re-insert each of these pre- >>>> existing rows that I need to fix up... now that's blindingly obvious. >>>> I welcome any commentary, though, on the sanity or insanity of my >>>> above paragraphs. Sqlalchemy rocks... >> >>>> Thanks! >>>> Eric >> >>>>> On Jan 1, 2011, at 9:52 PM, Eric Ongerth wrote: >> >>>>>> I must be doing something wrong but can't find it. >> >>>>>> I'm doing some database refactoring and found a situation where I had >>>>>> to set up a joined-table inheritance structure after the fact, with >>>>>> some of the tables already populated. I created (successfully) a >>>>>> script that got all of the primary and foreign keys right on all the >>>>>> child tables and the parent table, and now I just need to correctly >>>>>> populate the discriminator column on the parent table. >> >>>>>> Each row of the parent table is referenced by exactly one row from one >>>>>> of the six child tables. So i'm iterating through all child objects >>>>>> (yes, doing this via the sa ORM) and setting the value of the >>>>>> discriminator appropriately. Then I commit the Session. Afterward, I >>>>>> go and look at the parent table directly using pgAdmin and I see that >>>>>> the new values in the discriminator column were not saved. That's >>>>>> strange because I didn't get an error either, nor am I doing anything >>>>>> that would mask an error. >> >>>>>> So I thought maybe the discriminator column on the parent table in a >>>>>> joined-table inheritance scenario is just not watched by the Session / >>>>>> UOW. I thought maybe it assumes that this column would only, >>>>>> normally, be set during object instantiation and would typically not >>>>>> change for the lifetime of the object and its associated database >>>>>> rows. So I tried manually dirtying the object using >>>>>> instance_state(obj).modified=True before committing the Session. >>>>>> Still no success, the new values don't get saved. >> >>>>>> Is going outside of the ORM the only way to get this done? I don't >>>>>> mind doing so, but I'm just trying to understand better why my initial/ >>>>>> intuitive approach didn't do the job. >> >>>>>> Perhaps code / testcase will be requested and if I really can't figure >>>>>> this out I'll produce them, but it's really a pain in this case >>>>>> because it's a transient situation as part of a refactoring... I'm not >>>>>> looking forward to trying to create this once-only situation where I >>>>>> created the whole of a joined-table inheritance setup without telling >>>>>> sqlalchemy about it, then table by table altered the keys and mappers >>>>>> until everything was in place. Normally I wouldn't operate like >>>>>> this. Poor excuse, perhaps, but I'll stand by it for today. >> >>>>>> -- >>>>>> You received this message because you are subscribed to >> >> ... >> >> read more ยป > > -- > 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. > -- 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.