On Mar 17, 2006, at 11:57 AM, Jonathan LaCour wrote:
I think that you are going to find more and more people who want to
do things differently than this, and I think it would be a valuable
option for SQLAlchemy to support a lighter, more database-y ORM
methodology in addition to the way it behaves now. This is what
Aaron Bickell (one of my coworkers) ran into when trying to replace
our home-grown database layer with SQLAlchemy, and what inspired
him to write his simple object layer.
In the application Aaron was working with, we rely entirely on the
database for transactions, we use sequences for all primary keys
(we have to support databases that do not have SERIAL or
AUTOINCREMENT columns, and we have many use cases where we need to
know the IDs before we do our insert). We don't need or want to
cache anything. Our current database layer is very similar to the
basic Table objects in SQLAlchemy, and we use those to do all of
our CRUD operations against our tables.
SQLAlchemy has no dependency on SERIAL or AUTOINCREMENT whatsoever,
its just the default behavior when no other method for IDs is
specified, and no existing IDs are located for a given row to be
INSERTed. you can define whatever sequence, SQL function, or python
function you want and use those to define IDs at any point. When the
UOW/mapper goes to insert a record, it doesnt look to see "if theres
a primary key value already" to determine if its INSERT or
UPDATE...it looks to see if that object has an _instance_key and if
its already in the Identity Map. if a primary key value is already
defined for a row to be INSERTed, it leaves it unaffected.
Also SQLAlchemy has no caching, see below...
I think there are people out there who really want something like
this:
1. Transactions are entirely managed through the database. When
you start a transaction, it immediately issues a "BEGIN"
against your connection.
2. All SQL is emitted immediately, not buffered up and issued when
you commit. (This is needed also to support the above).
3. Any errors result in a "ROLLBACK" against the connection.
4. No caching of objects. This can be done in a different layer
if needed.
5. You can use table objects directly in the same transaction as
mapped objects, with no ill effects. Table operations will
also immediately emit SQL to the connection.
SQLAlchemy supports all of these patterns right now.
1. transactions can be manged in the database external to an
objectstore.commit: http://www.sqlalchemy.org/docs/
unitofwork.myt#unitofwork_begincommit_transactionnesting
2. SQL is emmitted immediately: use objectstore.commit(obj1, obj2,
obj3) as in http://www.sqlalchemy.org/docs/
unitofwork.myt#unitofwork_begincommit
3. errors result in a rollback: see #1
4. SQLAlchemy doesnt cache objects. If the identity map, which is
not a cache, is screwing you up, then I would question the
architecture of such an application that requires mulitple copies of
the same object in a single transaction. *and*, you can also have
multiple Sessions in scope at one time, so you *can* have multiple
copies anyway with some restrictions.
5. you can use tables directly using the approach outlined in #1.
6. The UnitOfWork's more powerful level of operation, that is the
commit all at once, is designed to elimainate a lot of the buggy
behavior that the approach in #1-5 is prone to (just read some Fowler
for background). It does allow custom SQL to be embedded in the
commit operation, which is accomplished via the MapperExtension:
http://www.sqlalchemy.org/docs/
adv_datamapping.myt#adv_datamapping_extending
I think Aaron's simple object layer is trying to address this in
part, but it would be great if we didn't have to have two entirely
different object layers in SQLAlchemy. It seems more ideal to have
one basic layer that can behave either way, depending on your
applications' needs.
I think its a matter of SQLAlchemy approaching the problem space from
a different perspective, and porting an old app that uses the typical
CRUD patterns may be challenging in some cases. SQLAlchemy doesnt
preclude the usage of those patterns, but this is that same issue
again; if we put a huge "CRUD" layer into SQLAlchemy's core, then
"the way to build your app" becomes a lot more confusing. I have no
problem with other ORM's being built upon SA's SQL layer but i think
it would be very difficult to merge that approach in with the current
UOW-oriented approach, theyre two different ways of thinking.
Not sure how you feel about this though...
I'd like to avoid SA becoming muddled with too many approaches in its
core, which is why ActiveMapper, which I think is a good idea, is
still out "over there".
-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
_______________________________________________
Sqlalchemy-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/sqlalchemy-users