Somebody in our local Python group was doing that, although not with
Pyramid. He ran a PostgreSQL consultancy, and one of his staff gave a
talk about the benefits of using Postges' role system for user
accounts and permissions, and custom Postgres functions for querying
and modifying data. They had a Python library to put a simple
ActiveRecord-type object layer over a Postgres function, so that you
could call functions and get/set attributes to access field data. I
don't remember the company name or the name of the library. The owner
was something Drake.
Are you aware that SQLAlchemy can be used either with or without the
ORM? You can use it simply to pool database connections, writing SQL
strings with replaceable parameters, and accessing results as tuples,
like the base DBAPI libraries (psycopg2 etc). Or you can define table
objects and use the query builder, and get results as keyed tuples
(fields accessed as a[0],
a.name, or a["name"]). Or you can go the
whole ORM route and have results converted to OO objects, and set
attributes on them and call methods to modify data. The upcoming
SQLAlchemy 2.0 unifies these two approaches more, giving the SQL
builder, ORM system, and result/transaction management a common
interface. You can enable this syntax with a future flag in SQLAlchemy
1.4.x.
But SQLAlchemy's code is certainly very complicated, and it has a lot
of layers for flexibility that you may not think are necessary. I've
gone both ways on using the ORM vs just using the SQL builder. There's
some overhead in converting database tuples to/from Python objects,
which is noticeable at maybe 10,000 (?) records. The overhead may be
less in frequent versions. So sometimes I define ORM classes in an
application and mostly use them, but in certain functions or scripts
that don't need them I go down to the SQL builder level. But you may
want to avoid all that overhead and complexity and just use the
database library (e.g., psycopg2) directly.
In one application, that's both a website and a desktop application
and a mobile app, the website and desktop wrapper were written in
Pylons in the late 2000s. (Pylons was one of Pyramid's ancestors.) Due
to other organization priorities, I'm only now converting it to
Pyramid. We tried to use the codebase in the mobile app, but Android
insisted on only Java or Javascript. (There are more workarounds
around that now, but there weren't then.) So we hired a Javascript
expert to reimplement the application in Javascript for the mobile
app. The website uses SQLAlchemy ORM. The mobile app can't, so the
developer did what she usually does, and wrote raw SQL statements with
replaceable parameters for every query. It's a read-only database so
there are no instert/update/delete complications. The database is
built ahead of time, via a Python script that uses SQLAlchemy's ORM.
We still use Pylons/Pyramids' transaction system ('pyramid_tm')
because it's in the default application example, but I doubt it's
adding any value for a read-only database. So I might eliminate it
someday. But then how would I open/close connections? Currently I have
a Request subclass with a reified property that creates a DB session
and registers it with 'pyramid_tm', and I let the transaction
mechanism rollback/close the session at the end of the request. I'm
not sure how to automatically rollback/close it otherwise, and I don't
want every view to have to do it, or count on reference
counting/garbage collection to close it. (I store the application-wide
db engine in a registry attribute.)
Mike Orr <
slugg...@gmail.com>