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.

Can you please explain a bit more what the expiration does (if I did not get it right)?

Or is there another solution? Is the design of my data structure (meaning
having mapped classes simultaneously as tree nodes) crap?

oh.  What's this mean ?   I can't imagine what you'd be doing there.   If
it were like:

def foo(data):
    class Foo(object):
        data = data
    mapper(Foo, sometable)
    return Foo

for x in (1, 2, 3):
    myobject.collection.append(foo(x))

that would be more or less insane, sure.  But even then.
myobject.collection is definitely not a SQLAlchemy instrumented attribute
- because its contents would have to be instances of a mapped class.  So
even with the above (entirely unnecessary and crazy) pattern, I don't see
how expiration is getting in the way.


This means: I have three declarative classes: Category, Asset and Note. An Asset belongs to one category and a note belongs to one asset. This is basically a tree structure, and can be reproduced with a relational database and therefore sqlalchemy. The classes just have additional methods like:

def child(self,row):
        return self.somerelation[row]


to tell the Qt API, that i am using as a gui toolkit, which instance to use in the tree. As said I think the problem lies there, because the api keeps internal pointers to the individual items of a query result, but on a commit they are expired and then changed by another query when accessed again, so the toolkit can't find them any more. Turning off expiration is the key.

if you want to know more about the crashed I can send you an test script.

Thank you

Sebastian

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

Reply via email to