You are welcome,
I get a lot of help from here, taking some load of Michael's back is the least 
I can do.

I got the idea from your story that you needed to understand how the mechanics 
are.

I'm blessed in having very complex polymorphic self relating setups with lots 
of mixins and Object functions. 
I remember the days I had issues like you and those can be very frustrating

I used capital letters to make clear you had to include the Id and you wrote 
code to exclude it ;-)

I would do something different on the continue, I do not like that code wise.

I would do domething like:

for column in [column for column in rec.__table.columns if c.name not in 
['discriminator']]:
        setattr(…...


with that you can easily add columns to exclude as your objects get more 
complex.

I use the above in a __iter__ method like this to create a dict which to 
convert to json and return to the browser

class ...

    skiplist = [] # or ['discriminator','somecolumn', 'somecolumn']

    def __iter__(self):
        for c in [c for c in self.__table__.columns] + [c for c in 
BaseObject.__table__.columns if c.key not in self.__table__.columns] and c.key 
not in self.skiplist]:
            if c.name not in ['ACLLinkId']:
                if isinstance(c.type, DateTime) and getattr(self, c.name) != 
None:
                    value = getattr(self, c.name).strftime('%Y-%m-%d %H:%M:%S')
                elif isinstance(c.type, Date) and getattr(self, c.name) != None:
                    value = getattr(self, c.name).strftime('%Y-%m-%d')
                elif isinstance(c.type, Time)and getattr(self, c.name) != None:
                    value = getattr(self, c.name).strftime('%H:%M:%S')
                else:
                    value = getattr(self, c.name)
                yield(c.name, value)

In fact I have Overridden the SA Column and added my own parameters to generate 
javascript.

Great it helped you

Martijn

On Jan 18, 2012, at 22:06 , Thierry wrote:

> Hi !
> 
> Thanks for the prompt, and very helpful answer
> I do now understand the logic a bit better
> 
> I've been able to get somewhere, so here's a status in case this is
> helpful
> 
> in my own example, Record is the ancestor/common class (x in your
> msg), and User is the specialization (y)
> 
> --- attempt #1
> the code below kind of works - [[I've naively tried to do the copy in
> some generic way, feel free to comment that part]]
> 
>    # locate the object to be promoted to specialized class
>    rec=session.query(Record).filter_by(hrn=hrn2).first()
>    user=User(None,None)
>    # copying the ancestor fields except primary_key and disciminator
>    mapper=object_mapper(rec)
>    for column in mapper.columns:
>        cname=column.name
>        if cname == mapper.polymorphic_on.name: continue
>        if column.primary_key: continue
>        setattr(user,cname,getattr(rec,cname))
>    # add new instance, trash previous one
>    # set a user-specific column
>    user.email="[email protected]"
>    session.add(user)
>    session.delete(rec)
>    session.commit()
> 
> however the side effect is that the new object - of course - has a
> different primary key, which in my case can work at this early stage,
> but I'm concerned about any possible relationship that would have a
> hard time with that
> 
> --- attempt #2
> and if now I comment out this line here, I'm getting a runtime error
> #        if column.primary_key: continue
> in order to try and reuse the same primary_key
> 
> Traceback (most recent call last):
> ...
>  File "tuto.py", line 79, in add2     <---- this is the commit line
> mentioned above
>    session.commit()
> ...
>  File "/usr/lib/python2.7/site-packages/sqlalchemy/orm/mapper.py",
> line 1867, in _save_obj
>    (table.description, len(update), rows))
> sqlalchemy.orm.exc.StaleDataError: UPDATE statement on table
> 'tuto_users' expected to update 1 row(s); 0 were matched.
> 
> --- attempt #3
> eventually I got this to do what I wanted by doing; just had to trash
> & commit the deprecated instance, before I could add and commit the
> new one
> 
>    # locate the object to be promoted to specialized class
>    rec=session.query(Record).filter_by(hrn=hrn2).first()
>    user=User(None,None)
>    # copying the ancestor fields except primary_key and disciminator
>    mapper=object_mapper(rec)
>    for column in mapper.columns:
>        cname=column.name
>        if cname == mapper.polymorphic_on.name: continue
> #        if column.primary_key: continue
>        setattr(user,cname,getattr(rec,cname))
>    # trash previous one
>    session.delete(rec)
>    session.commit()
>    # set a user-specific column
>    user.email="[email protected]"
>    # add new one
>    session.add(user)
>    session.commit()
> 
> --- and for the record
> # rpm -q python python-sqlalchemy postgresql
> python-2.7-8.fc14.1.i686
> python-sqlalchemy-0.6.8-1.fc14.i686
> postgresql-8.4.9-1.fc14.i686
> 
> 
> 
> -- Thanks again  -- Thierry
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "sqlalchemy" group.
> To post to this group, send email to [email protected].
> 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.
> 

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to [email protected].
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