Hello VP, 

niphlod is right. It does not apply to the DAL only to ORMs. Another way to 
put it, the DAL does not have it because it is contrary to the 
DAL philosophy.

The SQLA docs (http://www.sqlalchemy.org/features.html) say "SQLAlchemy's 
Object Relational Mapper (ORM), organizes pending insert/update/delete 
operations into queues and flushes them all in one batch."

Armin's explains this better here 
(http://lucumr.pocoo.org/2011/7/19/sqlachemy-and-you/): 
"SQLAlchemy follows the “Unit of Work” pattern whereas Django's ORM follows 
something that is very close to the “Active Record” pattern.... In 
SQLAlchemy you have an object called the “session”. It basically 
encapsulates a transaction. However it does more. Each object is tracked by 
primary key in this session. As such each object only exists once by 
primary key. As such you can safely make a lot of queries and you never 
have things out of sync. When you commit the session it will send all 
changes at once to the database in correct order, if you rollback the 
session nothing happens instead."

This exist because in any ORM Python instructions do not map 1-to-1 to SQL 
statements. In the DAL expressions map 1-to-1 to SQL statements (this is 
what we consider a feature) and they are issued immediately, not queued. 
For example db(...).select() is "SELECT...", db(...).update() is "UPDATE 
...", db(...).delete() is "DELETE ...", db.table.insert(...) is "INSERT...".

I can see why "unit of work" support would be useful in some circumstances, 
in particular to "rollback" without any DB interaction. Yet is seems to me 
it moves to python code something that the database is really good at doing 
already.

I do not fully understand how this is implemented in SQLA and how this 
affects queries involving multiple records. 

One thing that may or may not be relevant. In DAL you can do:

   row = db(..).select.first()
   row.field1='value1' # no db update
   row.field2='value2' # no db update
   row.update_record() # single db update

instead of 

   row = db(..).select.first()
   row.update_record(field1='value1') # first db update
   row.update_record(field2='value2') # second db update

You can also do

   db.table.bulk_insert([dict(field1='value1'),dict(field1='value2'),...])

instead of

   db.table.insert(field1='value1')
   db.table.insert(field1='value2')

It is not clear to me if SQLA can have multiple sessions per thread. Web2py 
cannot. If SQLA can, that is a plus. Web2py can only do it by having 
distinct db connections.

Massimo




On Sunday, 9 December 2012 09:30:39 UTC-6, VP wrote:
>
> I don't quite understand how this works.  That's why I am asking a 
> question if webp2y supports this so-called feature called "Unit of Work", 
> something that SQLAlchemy supports.   It is possible that this concept does 
> not apply to web2py DAL.  I don't know.  I have a feeling you are defensive 
> about this and view this as some kind of criticism of web2py.

-- 



Reply via email to