On Oct 13, 12:14 pm, "Tomasz Nazar" <[EMAIL PROTECTED]> wrote:
> 1) all model classes are defined in 1 file together with database mapping

like everyone is saying, you can roll this however you want and
however is appropriate to the type of app you're building.

>
> 2) SQLAlchemy 2nd level cache
>
> That is most frustrating for me coming from Hibernate, where it's
> built in. You may point to memcached or whatever, but the truth is it
> improves performance and coding style hugely!
> I would love to optimize later and be a bit lazy.
> Maybe the authors do not have resources -- it's a great soft anyway --
> but that should be one of the 1st features on the roadmap.

Hibernate makes a big deal out of second level cache because it makes
too small a deal out of eager loading.  Hibernate's eager loading is
fundamentally broken since you can't use it on a result set that has
LIMIT/OFFSET applied to it - the outer join gets wrapped inside the
LIMIT.   Their own docs think eager loading is a fairly rare use case,
because they're coming from that old EJB mindset of "entity beans"
stored in a giant in-memory hashtable against their primary keys,
which assumes that most relations are many-to-one's which can just
pull from the giant vat of identifiers when needed.  This was one of
the original issues SQLA sought to solve, and makes it a whole lot
easier to load several levels of objects, with or without a LIMIT/
OFFSET applied to the overall results, with only one round trip.

But eager loading isn't as good as no loading at all - so onto caching
for SQLA.  There's some reasons they're inconvenient.   ORM mapped
objects usually need to load additional data (i.e. lazyloading) which
implies an association with an active database connection.  Caching
the ORM objects means you have to dance around all the lazy loaders to
ensure none fire off, since there is no active database connection -
furthermore, even if you re-associated them with one, now you have a
concurrency issue.

Secondly, its incredibly common to get some ORM mapped objects from
somewhere and start using them in a transaction.  If you get them from
a cache, again you lose because they're global objects - you can't map
them back to your transaction.  So ORM caching which seems very simple
and automatic quickly leads to some very broken use cases for those
who don't understand what they're doing.

To fix the above two issues, SQLA offers the merge(dont_load=True)
method, which allows you to take your cached objects and associate a
copy of them with the current Session.  Though the overhead of copying
objects from the cache into the Session might not be that much cheaper
than the typical SQL query (and certainly doesn't save you anywhere
near the overhead that view layer caching does).

Here's a real simple 2nd level ORM query cache for SQLAlchemy which
does the merge thing and provides an easy Query interface:
http://www.sqlalchemy.org/trac/browser/sqlalchemy/trunk/examples/query_caching/query_caching.py
.  As of yet, nobody has sought to embark upon a "SQLAlchemy 2nd Level
Caching" project, but if there were this might be where they'd
start.   If you swap out the dictionary there for a Beaker cache,
there's your 2nd level Hibernate-style cache sans XML pushups.

But concerning that method, I've built SQL statement caches in the
past (caching objects which represent result sets mapped to SQL
strings, without the ORM issues mentioned above) and not had good
results due to the huge tree of SQL statements and result sets which
get generated.  Caches at this layer are complicated to manage, zone,
and expire, and ultimately don't address enough of the performance
overhead of the full request-to-render process.  So the biggest reason
that ORM caches aren't so critical is that caching for a web
application is extremely effective at the view layer.    If you've
spent a lot time with Java/JSP, this might not be apparent since view
layer caching support is abysmal in servlets/jsp/struts/taglibs/tiles/
etc. (more EJB fallout).

Pylons and Mako offer some of the most flexible view level caching
around - you can cache controller methods, functions, template
renders, and individual components (defs) of templates.  I recently
just wrote a small <%def> which sits in the globally inherited layout
template, wraps the middle of the page in a conditional cache which is
enabled and configured by a method called in the controller - so that
context-sensitive info in the header (like login info) stays context
sensitive, the content-heavy middle is optionally cached, all the
parameters and zoning of the cache is configured at the controller
level, the ORM fetches data purely from the DB (but less often), and
none of the templates have any idea whether or not they're cached or
for how long.   This is likely the subject of my next Pylons/Mako blog
entry.

View level caching usually reduces the size of data which is cached,
since you are caching just the HTML, not fully pickled class
instances, their full graph of dependencies, and the possibly many
result sets which all go towards building a fragment of HTML.  It
organizes caching around physical website regions which correspond
directly to more heavy or lesser trafficked views, and has the
strongest impact on performance since it removes not just the overhead
of fetching rows, but all the overhead of ORM invocation, query
construction, and template rendering.   HTML itself is a string and
doesn't have to be pickled/unpickled in order to store/retrieve from a
file or memcached (or if it is pickled, the process is extremely fast
since its a one-node object graph).

> 3) "flash messages" : data persisted somewhere between http session
> and http request, which lives through one session of http redirects,
> but then is purged.

this is included with Pylons 0.9.7:

helpers.py:

from webhelpers.pylonslib import Flash
flash_success = Flash(session_key="foobar")

controller:

h.flash_success('Operation complete')
redirect_to(whereever)

template:

% for msg in h.flash_success.pop_messages():
   ${msg}
% endfor

> 4) CRUD: generate view + controller methods
>
> Having controller file with CRUD methods already defined (using SQLA)
> and redirecting to template files would be nice to have.
> I don't need that at this stage of project, where I use custom views
> all over the place. But for beginners it would be nice to have
> CRUD*.mako(s) created (as option?) and to have working application
> almost instantly.
> It's often said that Django does that, and Pylons not :(

heh but you came from Java ?  :).   Pylons caters a little more to the
do it yourselfer crowd I guess...there isn't a "standard" way to
organize the CRUD/redirection/etc. steps, especially when ajax comes
into the equation.  I certainly wouldn't want the web framework to pre-
write all the code since I'm going to have my own usage patterns which
differ from what someone else thinks they might be.   So a generic
"repeat me!" tool might fit this bill....though I thought PasteScript
already did this in some way...

> 5) easy_install pylons - Beta
>
> It's a minor, but let me say that: When last time I installed Pylons
> in Windows for a friend, it downloaded some eggs which were beta stage
> (sqlalchemy?). I just know that proper 0.9.6 app was not working.. We
> had to downgrade few eggs to make it work.

setuptools has come a super long way in the past couple of years, with
plenty of great tools like Ian Bicking's virtualenv and zc.buildout
helping us out, and I'm confident we'll have the Python install story
nailed down pretty well sooner or later.  Django of course hasn't
participated in any of this but I'm sure they'll be glad to come on
board once all the hard work is done ;).

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"pylons-discuss" 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/pylons-discuss?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to