Hello alchemers -
This is an awesome release. I'm excited about this one. With our new
shiny clean 0.4 codebase, internals are starting to look a lot more
intelligent, and new things are becoming possible. Call counts are
going down like a rock. Intents and behaviors are clarifying and
sharpening....plus Super Mario Galaxy arrives tomorrow so its time for
a break.
Some highlights of this release:
- you might notice that some eager load operations are suddenly a lot
faster, particularly on MySQL. This is because we've improved the
queries that are issued when you use eager loading with LIMIT and/or
OFFSET; whereas we previously would wrap the LIMITed query in a
subquery, join back to the mapped table, and then add the eager
criterion outer joined against the mapped table, a trick we've been
doing since 0.1.0, we now outer join the eager criterion directly
against the subquery, and the main mapper pulls rows straight from the
subquery columns. Improved SQL expression functionality has allowed
this to be possible. What it means is, an eager load with LIMIT/
OFFSET uses one less JOIN in all cases. This is an example of SA's
very rich expression constructs paying off - since a query that is
much more efficient on the database side trumps the hundred or so
method calls spent compiling the query anyday.
- session.refresh() and session.expire() can now operate on individual
instance attributes. Just say session.expire(myobject, ['items',
'description', 'name']), and all three of those attributes, whether
they're just columns or relations to other objects, will go blank
until you next access them on the instance, at which point they are
refreshed from the DB. Column attributes will be grouped together in
a single select() statement and related tables will be lazy loaded
individually right now. Also, the internal mechanisms used by
deferred() columns, refresh/expire operations, and polymorphically
deferred columns have all been merged into one system, which means
less internal complexity and more consistent behavior.
- the API of the session has been "hardened". This means its going to
check more closely that operations make sense (and it also no longer
raises some errors that did not make sense in certain circumstances).
The biggest gotcha we've observed so far from people using trunk is
that session.save() is used *only* for entities that have not been
saved to the database yet. If you put an already-stored instance in
save(), you'll get an error. This has always been the contract, it
just hasn't complained previously. If you want to put things in the
session without caring if they've already been saved or not, use
session.save_or_update(myinstance). We've also fixed things regarding
entities that have been de-pickled and placed back into the session -
some annoying errors that used to occur have been fixed.
- still in the session category, the merge() method gets a
"dont_load=True" argument. Everyone using caches like memcached can
now place copies of their cached objects back in the session using
"myinstance = merge(mycachedinstance, dont_load=True)", and the
instance will be fully copied as though it were loaded from the
database, *without* a load operation proceeding; it will trust that
you want that instance state in the session.
- query.options() are way more intelligent. Suppose you have a large
bidirectional chain of relations. If you say something like
query.options(eagerload('orders.items.keywords.items.orders')), it
will accurately target the 'orders' relation at the end of that chain
and nothing else. On a similar topic, self-referential eagerloads can
be set up on the fly, such as
query.options(eagerload_all('children.children.children')) without
needing to set the "join_depth" flag on relation().
- method call overhead continues to be cut down. Many expensive calls
in statement compilation, clauseelement construction, and statement
execution have been whacked away completely and replaced with simpler
and more direct behaviors, and results are more accurate and correct.
This continues along from all that we've done in 0.4 and at this point
most call counts should be half of what they were in 0.3. I invite
everyone to take a tour around expression.py, compiler.py, and
critique; we've had a huge amount of housecleaning in these modules
(and others), and further suggestions/ideas/flames are entirely
welcome (though not too early in the morning) on sqlalchemy-devel.
- in the fringe category, you can now define methods like __hash__(),
__nonzero__(), and __eq__() on your mapped instances and the ORM won't
get confused; we've rearranged things so that those methods are not
accessed by the ORM.
- a new, experimental MaxDB dialect, lots of typing fixes for MySQL
and Oracle, and lots more.
As always, the full list of changes is at http://www.sqlalchemy.org/CHANGES
. Check it out then download at http://www.sqlalchemy.org/download.html
.
- mike
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"sqlalchemy" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/sqlalchemy?hl=en
-~----------~----~----~----~------~----~------~--~---