views:

109

answers:

1

I need some guidance on how to use session objects with SQLAlchemy, and how to organize Unit Tests of my mapped objects.

What I would like to able to do is something like this:

thing = BigThing() # mapped object
child = thing.new_child() # create and return a related object
thing.save() # will also save the child object

In order to achieve this, I was thinking of having the BigThing actually add itself ( and it's children ) to the database -- but maybe this not a good idea?

One reason to add objects as soon as possible is Automatic id values that are assigned by the database -- the sooner they are available, the fewer problems there are ( right? )

What is the best way to manage session objects? Who is in charge of the session?
Should it be created only when required? or saved for a long time?

What about Unit Tests for my mapped objects?...how should the session be handled? Is it ever OK to have mapped objects just automatically add themselves to a database? or is that going to lead to trouble?

+1  A: 

Session is like a box where you store objects. Sure you can write __init__ method to automatically add object to it, but this implies that it's there is some global (the only) session. Sure this will cause problems in a lot of cases, but also this will simplify writing code a bit. It's explicit vs. implicit dilemma. Some people follow Zen of Python, and some don't. I prefer to specify a box to store explicitly.

Note, that there is no need to add children to session explicitly as far as it is associated with object already in session via relation. That's what cascading rules are for. The default 'save-update' does exactly what you request. You might be also interested in 'all, delete-orphan' to implement "private" objects, which should be deleted along with their parent.

I see some problems to implement save() method. There is no way to say "save this objects" in SQLAlchemy in current version. There was such ability earlier, but it was never reliable. Session.flush() (it's called from Session.commit()) flushes all changes to the database. This is probably the most annoying feature of SQLAlchemy that prevents me from using it in certain projects.

Unit testing is very easy (at least when you specify session explicitly), see the sample code in other question.

Denis Otkidach
Ok, I can understand that: "a box of objects"...so it's like a container for all the related objects that I am working with at one time, where all of the objects are to be committed to the database together. I suppose for unit-testing there should be one session per test. For a web-server, one session per request(?). And for a desktop app...could there be just one session for the life of the app?...or should there be a new session for every "operation" that is performed? Can you "empty the box" when you are done and re-use it?
Nick Perkins
You can use a single session for the whole desktop app and can use separate for each task. The later is somewhat slower, but more reliable. There is `expunge_all()` method to clear session.
Denis Otkidach