Hello Michael, hello Conor,
thanks for the detailed help, obviously this is a problem of PyQt. I
tested Conors suggestion with the strong references this morning, no
crashes, this is my solution for now. So its like you said, the objects
pointed to get garbage collected prematurely. I would never have thought I
would say this, but now I'd like to go back to c++ :)
I am already using the newest build of PyQt, so I guess I will post on the
mailing list there.
Thank you,
Sebastian
On Wed, 24 Mar 2010 21:06:10 +0100, Michael Bayer
<[email protected]> wrote:
Sebastian Elsner wrote:
My first question is: What exactly is the commit doing to the list
returned from the query so that pointers to other objects are "lost"
(python.exe will crash on me then)?
The commit expires all attributes by default, since the transaction is
committed, and upon next access will be loaded again from the database.
Feel free to turn this flag off if you don't want the reload.
There's no reason why any of this would crash the interpreter, however.
It only means your model will refresh its information from the
database.
The expiration was the problem. As soon as I turned it off, the errors
and
crashes went away
I was getting:
Attribute Error: "SomeClass" object has no attribute
'_sa_instance_state'
This happened when:
list=session.query(SomeClass).all()
list.somerelation.append(SomeRelatedClassInstance)
session.commit()
The docs state:
expire_on_commit
Defaults to True. When True, all instances will be fully expired after
each commit(), so that all attribute/object access subsequent to a
completed transaction will load from the most recent database state.
This means, when I access an expired attribute it will issue another
query
creating a new instance of the attribute/relation I wanted to follow?
Subsequently the memory address will change? Do I understand this
right?
I am asking this, because the Qt Tree i am using to display the data
heavily relies on "internal pointers", so you would have a dangling
pointer pointing to nowhere, which would explain the crashes.
if QT is maintaining a "reference" to something using its "memory
address", but is not actually recording a strong reference to the object
within the python interpreter, that sure sounds like a bug to me. It
would imply that to use that library, every object you generate in Python
must have a strong reference maintained, or QT now references invalid
ids.
If I were using such a library, I'd probably do something to my classes
such that any instance created automatically puts itself into a set()
somewhere, using a metaclass. The object then can never be garbage
collected unless you called a custom "dispose()" method that would remove
it from the set. It sounds like a massive interpreter leak waiting to
happen but QT seems to demand that such measures are taken.
As far as the Session, as long as you have a strong reference to every
object you care about, they don't go anywhere, and identity (a better
term
for "memory address" when we're in an interpreted language) doesn't
change. The *connection* between A->B would be broken during an
attribute expiration, but A and B themselves would still be present and
become reattached. This is the basic idea of the identity map.
So the Session is not intended to provide "strong references" to things.
It's not a cache, and the fact that A points to B is only a
representation
of database state. If you prevent the session from expiring its
representation of state, then the reference between A and B will remain.
But its a little tenuous to rely upon this behavior to ensure that a
third
party library which requires strong references in order to keep from
crashing. If the stability of your application is at stake I'd want to
own that mechanism outside of my ORM.
--
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.