Cool, that should be fine for my current application, thanks =)

-Dave

-----Original Message-----
From: sqlalchemy@googlegroups.com [mailto:[EMAIL PROTECTED]
On Behalf Of Michael Bayer
Sent: Friday, October 27, 2006 3:32 PM
To: sqlalchemy@googlegroups.com
Subject: [sqlalchemy] Re: related object list not being updated on
delete


OK yeah, the relation() idea is not nearly smart enough to figure out  
what you mean there, or to even support overlapping collections (i.e.  
if you didnt have "nodes", it could work with just "algorithms" and  
"parameters").   the two extra relations could be implemented with a  
custom join condition on the "polymorphic_on" column, and with a  
"viewonly=True", but that will not stay in sync with modifications to  
the "nodes" collection unless you flushed and refreshed.

the simplest approach would just be:

class Project(object):
        algorithms =property(lambda self:[x for x in self.nodes if
isinstance 
(x, Algorithm)])
        parameters =property(lambda self:[x for x in self.nodes if
isinstance 
(x, Parameter)])

mapper(Project, Project.table, properties = {
                'nodes':relation(Node, backref='project', cascade='all,
delete- 
orphan')
        })

and you localize collection mutating operations to just the "nodes"  
collection.  if you want to be able to append elements to each  
collection, it would have to be some custom collection class that can  
export "filtered" versions of itself that still support appending to  
the master list, which is referenced by the "nodes" property.

if Node is an abstract (uninstantiated) class, you could do it the  
other way around too, i.e. algorithms and parameters are the "real"  
collections and "nodes" is just the sum of both.


On Oct 27, 2006, at 3:00 PM, Hogarty, David A. wrote:

> Here's a quick example script, illustrating what I'm trying to do
>
> -Dave
>
> -----Original Message-----
> From: sqlalchemy@googlegroups.com [mailto:[EMAIL PROTECTED]
> On Behalf Of Michael Bayer
> Sent: Friday, October 27, 2006 1:42 PM
> To: sqlalchemy@googlegroups.com
> Subject: [sqlalchemy] Re: related object list not being updated on
> delete
>
>
> can you show me your full mapping ?  im confused how the Parameter
> instance would be present in two collections on the same parent
> object at the same time.
>
> On Oct 27, 2006, at 1:28 PM, Hogarty, David A. wrote:
>
>>
>> That might be worth doing... the example I gave of deleting from both
>> lists seems to fail erratically based on when and how the lists were
>> referenced before removal.
>>
>> For example, the following:
>>
>> def test_node_polymorphism(self):
>>     p = Project(name='p')
>>     db.session.save(p)
>>     p.nodes
>>     p.nodes.append(Parameter(name='p1'))
>>     db.session.flush()
>>     assert len(p.nodes) == 1
>>     assert len(p.parameters) == 1
>>
>> passes, while adding a p.parameters reference before the assertions
>> causes the second assertion to fail, because len(p.parameters) is
>> still
>> 0 from the first reference
>>
>> def test_node_polymorphism(self):
>>      p = Project(name='p1')
>>      db.session.save(p)
>>      p.nodes
>>      p.parameters
>>      p.nodes.append(Parameter(name='prm1'))
>>      db.session.flush()
>>      assert len(p.nodes) == 1
>>      assert len(p.parameters) == 1
>>
>> -----Original Message-----
>> From: sqlalchemy@googlegroups.com  
>> [mailto:[EMAIL PROTECTED]
>> On Behalf Of Michael Bayer
>> Sent: Friday, October 27, 2006 10:37 AM
>> To: sqlalchemy@googlegroups.com
>> Subject: [sqlalchemy] Re: related object list not being updated on
>> delete
>>
>>
>> you could also implement a custom list class that *does* track itself
>> with items that are added/removed from it, and then implement a  
>> delete
>> (instance) method that removes the instance from all the lists its
>> contained within before doing a session.delete().  i might consider
>> adding an extension module for this since its not very hard to
>> implement.
>>
>> On Oct 27, 2006, at 10:12 AM, Hogarty, David A. wrote:
>>
>>>
>>> Thanks, I got it working. For future reference, if you have a
>>> polymorphic relationship, in order to avoid this kind of phantom
>>> object,
>>> you need to manually delete from both the parent collection and the
>>> child collection, e.g.
>>>
>>> Project (Has Many)-> Node
>>> Parameter (Subclass)-> Node
>>>
>>> to remove a parameter from a project, you need to do both
>>>
>>> project.parameters.remove(param)
>>> project.nodes.remove(param)
>>>
>>> -Dave
>>>
>>> -----Original Message-----
>>> From: sqlalchemy@googlegroups.com
>>> [mailto:[EMAIL PROTECTED]
>>> On Behalf Of Michael Bayer
>>> Sent: Thursday, October 26, 2006 5:43 PM
>>> To: sqlalchemy@googlegroups.com
>>> Subject: [sqlalchemy] Re: related object list not being updated on
>>> delete
>>>
>>>
>>> items dont get removed from collections when they are marked with
>>> delete().  with the exception of bi-directional relationships, SA
>>> doesnt add or remove items from collections.  to do so in this case
>>> would require tracking every collection which a particular item is
>>> contained within which would add both memory and performance
>>> overhead.
>>>
>>> the usual strategy is to mark the relationship with a "delete- 
>>> orphan"
>>> cascade, and then just remove the item from the collection, which
>>> will result in its getting deleted during the flush() operation.
>>>
>>> On Oct 26, 2006, at 5:13 PM, Hogarty, David A. wrote:
>>>
>>>>
>>>> I'm having a problem where phantom child objects stay attached to a
>>>> parent object after having been deleted. For example:
>>>>
>>>> def test_add_delete_parameter(self):
>>>>     p = Project(name='ptest')
>>>>     db.session.save(p)
>>>>     db.session.flush()
>>>>     p.parameters.append(Parameter(name='p1'))
>>>>     p.parameters.append(Parameter(name='p2'))
>>>>     p.parameters.append(Parameter(name='p3'))
>>>>     db.session.flush()
>>>>     id = p.parameters[-1].id
>>>>     param = db.session.query(Parameter).get_by(
>>>>         and_(
>>>>             Parameter.c.project_id == p.id,
>>>>             Parameter.c.id == id
>>>>             ))
>>>>     db.session.delete(param)
>>>>     db.session.flush()
>>>>     p2 = db.session.query(Project).get(p.id)
>>>>     assert len(p2.parameters) == 2
>>>>     assert len(p.parameters) == 2
>>>>
>>>> Both of the assertions at the bottom fail, because the project
>>>> instance
>>>> still believes it has 3 parameters attached. Is this a bug, or
>>>> should I
>>>> be deleting the parameters differently?
>>>>
>>>> -Dave
>>>>
>>>>>
>>>
>>>
>>>
>>>
>>>>
>>
>>
>>
>>
>>>
>
>
>
>
>
> > <davepoly.py>




--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---

Reply via email to