On Jan 10, 2014, at 1:42 PM, Paul Moore <[email protected]> wrote:

> On Friday, 10 January 2014 17:52:45 UTC, Michael Bayer wrote:
> there’s various patterns for dealing with the very common issue of “create 
> unique object if not exists, else use the current one”.  One that I 
> frequently point to is the unique object recipe: 
> 
> OK, so looking at that seems to imply that
> 
> pkg = Package(name="pip")
> session.add(pkg)
> is_it_there = session.query(Package).filter(Package.name == 'pip').first()
> assert is_it_there is pkg
> 
> will fail the assertion (unless there is a flush).

if autoflush is turned on, it will pass the assertion.  the Session is flushed 
before any SQL query when autoflush is left at its default of True. So first 
pkg goes in via INSERT, the SELECT is emitted, locates the row with the 
identity of pkg, locates “pkg” itself in the identity map, and returns it.


> Otherwise, I don't see why the unique cache is needed in the recipe you 
> reference.

the cache isn’t needed but is nice so that many objects all doing the same 
thing don’t have to keep hitting the database for an object that’s already 
local in memory.

keep in mind, the Query always emits SQL, except in the case of the get() 
method which will look locally in the identity map first.  Otherwise, as rows 
are returned from the SQL statement, the primary key identity of each row is 
matched to whatever objects are already in the identity map.   That’s how the 
identity map works.   You still get the SQL being emitted in most cases so it’s 
not quite a “cache”.   More detail on this here: 
http://docs.sqlalchemy.org/en/rel_0_9/orm/session.html#is-the-session-a-cache

Attachment: signature.asc
Description: Message signed with OpenPGP using GPGMail

Reply via email to