using pyramid without an ORM ?

85 views
Skip to first unread message

pzzcc

unread,
Aug 11, 2022, 11:53:31 AM8/11/22
to pylons-discuss
Hello ,

I am building an application ( more of a tool really ) that have a web interface , and I am trying to avoid using ORM all together. plus I want to try postgresql features and experiment more with them.

I don't want things to be overly complicated on the web interface so I put lots of logic , something that I know will not change any time soon , into PostgreSQL directly using functions etc.

can you please point me to the right direction of using pyramid without it ? what might be the pitfalls of not using an ORM with pyramid  ?



Thanks !

Steve Piercy

unread,
Aug 11, 2022, 12:12:24 PM8/11/22
to pylons-...@googlegroups.com
For starters, how will you convert the results of a query into a useful Python object? 

For more things, read SQLAlchemy's description and features.
 

--steve

--
You received this message because you are subscribed to the Google Groups "pylons-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pylons-discus...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/pylons-discuss/309895e7-5ea4-49c6-b7e3-d7dff9c62337n%40googlegroups.com.

pzzcc

unread,
Aug 11, 2022, 12:21:47 PM8/11/22
to pylons-discuss
Hello Steve ,

I would like to use psycopg2, I am reading this now :




but I would like to see if anyone can share his experience / or point any pitfalls.

what part of pyramid API should I look more into.

that would help me understand pyramid and postgresql more.

thanks Steve 

Eldav

unread,
Aug 11, 2022, 12:22:07 PM8/11/22
to pylons-discuss
Hello,

afaik, nothing forces you to use SQLAlchemy with Pyramid (after all, you could decide to use a non-relational database such as the ZODB or MongoDB).

If you are sure that you won't need database attraction later, you can talk to psycopg2/3 directly. By doing so, you will also lose the possibility to automatically synchronise SQL transactions with Pyramid. It may or may not be ok for you, depending on your problem, but it's certainly possible to implement the required mechanism if required.

On the other hand, you might decide to run your raw SQL queries via SQLAlchemy, without using the ORM parts. This would give you the transaction synchronisation, provided you remember to mark your DB session as changed (look for "mark_changed" in https://pypi.org/project/zope.sqlalchemy/#full-example) after an insert/update/delete query.

Hope this helps,

Laurent.

Eldav

unread,
Aug 11, 2022, 12:25:27 PM8/11/22
to pylons-discuss
sorry, database *abstraction* (stupid typo)

pzzcc

unread,
Aug 11, 2022, 12:31:47 PM8/11/22
to pylons-discuss
Thanks Eldav ,

yes I would like to implement my own really to have a better understanding of how things work.

thanks for the input and the resource.

Michael Merickel

unread,
Aug 11, 2022, 12:38:36 PM8/11/22
to pylons-...@googlegroups.com
As Laurent said, if I were starting from scratch a new project I would personally use the pyramid-cookiecutter-starter sqlalchemy and then rip out what I didn’t need but only one part of that cookie cutter is the ORM. It has several other features that you need to solve one way or another so you’d at least want to know what you’re getting rid of. It is modular and you can pick the layers you want.

- connection pooling
- transaction binding to request lifecycle to rollback or commit at optimal times
- tables mappings to assist in converting database types into python
- ORM objects a more comprehensive query language on top of those tables
- alembic for autogenerating migrations from those models and helping with database versioning

If you go with only the first couple layers you can rip the rest out and just use dbsession.execute() like you would in psycopg2 and just set the zope.sqlalchemy initial_state=‘changed’. 

You can accomplish everything done here without sqlalchemy as well - but you will still want to understand the layers and reasons for the fundamental patterns to hook into pyramid. The sqlalchemy part of the config can be replaced almost directly with psycopg2 versions of everything and it just ends up being more specific to that application. You will need to use the cookbook entries to manage your connections/transactions as I don’t think there’s a pyramid_tm binding for psycopg2 directly - although it’s likely easy to write that DataManager. 

- Michael

On Aug 11, 2022, at 09:25, Eldav <ldav...@gmail.com> wrote:


--
You received this message because you are subscribed to the Google Groups "pylons-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pylons-discus...@googlegroups.com.

pzzcc

unread,
Aug 11, 2022, 12:54:36 PM8/11/22
to pylons-discuss
Thanks Laurent and Michael.

I want to avoid using SQLALCHEMY all together really to have a better understanding of how things work inside pyramid for integrating the tool with other tools already in place. so I think that is the correct route. once I get this to work , I will have a deeper understanding of pyramid in general which will help integrating that tool into the system we already have in place .

thanks a lot for the input, I appreciate everyone's time.

Steve Piercy

unread,
Aug 11, 2022, 1:25:44 PM8/11/22
to pylons-...@googlegroups.com
Take SQLAlchemy, subtract psycopg2, the resulting differences are all the pitfalls you would get. There are too many to list, when the SQLAlchemy feature list gives you all that you need.

--steve

Mike Orr

unread,
Aug 12, 2022, 12:00:17 AM8/12/22
to pylons-...@googlegroups.com
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.)
> --
> You received this message because you are subscribed to the Google Groups "pylons-discuss" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to pylons-discus...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/pylons-discuss/309895e7-5ea4-49c6-b7e3-d7dff9c62337n%40googlegroups.com.



--
Mike Orr <slugg...@gmail.com>

Mike Orr

unread,
Aug 12, 2022, 12:10:54 AM8/12/22
to pylons-...@googlegroups.com
On Thu, Aug 11, 2022 at 9:54 AM pzzcc <grc...@gmail.com> wrote:
> I want to avoid using SQLALCHEMY all together really to have a better understanding of how things work inside pyramid for integrating the tool with other tools already in place. so I think that is the correct route. once I get this to work , I will have a deeper understanding of pyramid in general which will help integrating that tool into the system we already have in place

If you get out of SQLAlchemy and the transaction manager, then you're
getting out of Pyramid's database toolchains. I.e., you're
DEintegrating, not integrating. What you'll learn is the low-level
database API (psycopg2, based on Python's DBAPI interface). That's
worth learning about if you like low-level close-to-the-metal tools.
It can do simple tasks fine, but large abstract concepts or large
development teams may do better with something high-level like
SQLAlchemy.

SQLAlchemy's creator, Michael Beyer, has given talks at several
Pycons, and is friends with the people who created Pylons and Pyramid.
He's a super-expert on SQL. So there's also value in benefiting from
his expertise when you use SQLAlchemy, and when you look at how
flexible SQLAlchemy can be. He also wrote the Mako template engine.

Mike Orr

unread,
Aug 12, 2022, 12:21:09 AM8/12/22
to pylons-...@googlegroups.com
On Thu, Aug 11, 2022 at 8:59 PM Mike Orr <slugg...@gmail.com> wrote:
> 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.

I'm not saying I necessarily agree with the approach, just saying it exists.

The tradeoff is you lose the ability to run it on non-Postgres
databases, but you gain the ability to use Posgres' unique features.
Their attitude is that Postgres' code and its account system is
well-tested and secure, so why not use it to the max.

But it's not necessarily either/or. SQLAlchemy has several calls and
field types for features that only Postgres or a few databases
implement, so you can get the best of both worlds. You can call custom
Postgres functions from SQLAlchemy, both to query and to modify data.
I have some database views (virtual tables over real tables) that I
create in a raw SQL script, and then access them through SQLAlchemy
table/class objects. I do that because I have one site that
reads/writes a database, and another site that only reads a subset of
that database. So the views restrict the fields that can be seen.

Arndt Droullier

unread,
Aug 15, 2022, 5:28:28 AM8/15/22
to pylons-...@googlegroups.com
Hi,
I use Postgres and Pyramid without ORM. It's quite straight forward and I don't see any reason against this approach. 
'Connection Pooling' might be a problem because Postgres is quite slow when it comes to setting up new connections. If necessary you could handle it outside of Pyramid/Python by using pgBouncer.

You might need to have a look at the event system, especially NewRequest/NewResponse: 

Arndt.



I would like to use psycopg2, I am reading this now :




but I would like to see if anyone can share his experience / or point any pitfalls.

what part of pyramid API should I look more into.

that would help me understand pyramid and postgresql more.


--
You received this message because you are subscribed to the Google Groups "pylons-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pylons-discus...@googlegroups.com.

Jonathan Vanasco

unread,
Aug 15, 2022, 6:46:04 PM8/15/22
to pylons-discuss

I second what Michael said.  The sqlalchemy starter template is the right way to go.

The major thing this template does, is provide you with the glue between a SQLAlchemy "Session" and the pyramid request.  See : https://github.com/Pylons/pyramid-cookiecutter-starter/blob/latest/%7B%7Bcookiecutter.repo_name%7D%7D/%7B%7Bcookiecutter.repo_name%7D%7D/sqlalchemy_models/__init__.py#L87-L127

If you run pyramid_tm (https://pypi.org/project/pyramid-tm/) you can then use zope.sqlalchemy (https://pypi.org/project/zope.sqlalchemy/) to bind the session to the transaction.

You don't need to use SQLAlchemy's ORM.  You can just use SQLAlchemy Core (https://docs.sqlalchemy.org/en/14/core/) to do everything.  You can also access the underlying psycopg2 connections through SQLAlchemy when you want.

There is not a lot of code to rewrite if you want to eliminate SqlAlchemy and start from scratch - probably only 100-400 lines worth, and as Arndt Droullier said it is pretty straightforward -- but you're going to have to maintain that, and the entrypoints are somewhat rough.  Even in that situation, starting with the sqlalchemy cookiecutter is your best option as it will give you a better idea as to where your code needs to go.

Tom Willis

unread,
Aug 15, 2022, 8:23:23 PM8/15/22
to pylons-...@googlegroups.com
sqlalchemy core is a better option than going straight to the driver imo. And you can call postgresql functions from the session, however if you are using pyramid transaction and zope.sqlalchemy you will want to get in the habit of marking the transactions as changes were made for the functions that mutate data...


from zope.sqlalchemy import mark_changed
from sqlalchemy import func
result = session.execute(func.my_pg_func(*params)).scalar()
mark_changed(session)


--
You received this message because you are subscribed to the Google Groups "pylons-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pylons-discus...@googlegroups.com.

Mike Orr

unread,
Aug 16, 2022, 11:42:26 AM8/16/22
to pylons-...@googlegroups.com
On Mon, Aug 15, 2022 at 3:46 PM Jonathan Vanasco <jvan...@gmail.com> wrote:
>
>
> I second what Michael said. The sqlalchemy starter template is the right way to go.
>
> The major thing this template does, is provide you with the glue between a SQLAlchemy "Session" and the pyramid request. See : https://github.com/Pylons/pyramid-cookiecutter-starter/blob/latest/%7B%7Bcookiecutter.repo_name%7D%7D/%7B%7Bcookiecutter.repo_name%7D%7D/sqlalchemy_models/__init__.py#L87-L127
>
> If you run pyramid_tm (https://pypi.org/project/pyramid-tm/) you can then use zope.sqlalchemy (https://pypi.org/project/zope.sqlalchemy/) to bind the session to the transaction.
>
> You don't need to use SQLAlchemy's ORM. You can just use SQLAlchemy Core (https://docs.sqlalchemy.org/en/14/core/) to do everything. You can also access the underlying psycopg2 connections through SQLAlchemy when you want.

Is there a way to make 'pyramid_tm' always roll back even on success?
I looked in the code and there seemed to be no flag for that, and I'd
either have to call 'transaction.doom()' in a subscriber or patch the
obscure code several levels deep.

Mike Orr

unread,
Aug 16, 2022, 11:45:24 AM8/16/22
to pylons-...@googlegroups.com
It is rolling back in some of my testing when there's no
insert/delete/update, but I want to make sure it always does, just in
case something somehow modifies the database when we didn't intend to.
It's not that big a deal but it's what I'd like. I'm not sure if
SQLAlchemy is issuing rollback if there were no changes, or if it will
always do so.
--
Mike Orr <slugg...@gmail.com>

Jonathan Vanasco

unread,
Aug 16, 2022, 12:19:30 PM8/16/22
to pylons-discuss
On Tuesday, August 16, 2022 at 11:45:24 AM UTC-4 Mike Orr wrote:
> It is rolling back in some of my testing when there's no
> insert/delete/update, but I want to make sure it always does, just in
> case something somehow modifies the database when we didn't intend to.
> It's not that big a deal but it's what I'd like. I'm not sure if
> SQLAlchemy is issuing rollback if there were no changes, or if it will
> always do so.

That's from SQLAlchemy. It will rollback if there were no database writes.  SQLAlchemy is unaware of raw sql being a write operation, so you need to use the `mark_changed` function from zope.sqlalchemy.   This is a weird idiosyncrasy of SQLAlchemy and transaction - the transaction could be completely successful, but SQLAlchemy will rollback because there was no activity within it's scope. 

It sounds like you're trying to do the opposite of what the `transaction` package is designed to do.

The way I normally deal with situations like that is to control if SQLAlchemy joins the transaction or not.  In most projects, I only use the transaction on specific views that require this type of integration - such as anything that sends an email (pyramid_mailer integrates with pyramid_tm).

It also sounds like your concern is mostly in testing.  The approach I've started to standardize on is to have a database snapshot for tests and just recreate the database from that on every run.  If you just want to completely disable database commits though, you could have your test harness set up a SQLAlchemy event listener for "commit", and then issue a "rollback" within the event.

Michael Merickel

unread,
Aug 16, 2022, 4:30:23 PM8/16/22
to pylons-...@googlegroups.com
transaction.doom() is a good way. Another is to register a commit_veto hook in pyramid_tm. It is a hook that is invoked any time it would be about to commit, giving you a chance to stop it. Advantage of the veto is that you can register it from settings globally.

- Michael

> On Aug 16, 2022, at 10:42, Mike Orr <slugg...@gmail.com> wrote:
> --
> You received this message because you are subscribed to the Google Groups "pylons-discuss" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to pylons-discus...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/pylons-discuss/CAH9f%3DuqT58npmt6_sbfXJpVZ4hX7PNJdj1WqYXeXo7rJfhwPQQ%40mail.gmail.com.

Mike Orr

unread,
Aug 16, 2022, 5:50:02 PM8/16/22
to pylons-...@googlegroups.com
The SQLite database is pregenerated for a release and contains only
reference information. It's read only to the web application. So I'm
wondering if it's worth even hooking the session into the transaction
manager at all. I have a request subclass, and to open a session I use
a reified method:

@reify
def sa_session(self):
engine = self.registry.sa_engine # Attribute set during startup
configuration.
info = {"request": self} # Because this was in the tutorial.
sess = sqlalchemy.orm.Session(engine, info=info)
zope.sqlalchemy.register(sess) # Is this worth doing for a
read-only database?
return sess

The transaction manager closes the session for me, so without it I
guess I'd have to have a subscriber that rolls back and closes the
request. I don't want to have to do it in every view because it's not
view-specific logic.
> --
> You received this message because you are subscribed to the Google Groups "pylons-discuss" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to pylons-discus...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/pylons-discuss/771e180a-ca5b-4625-baf7-972d237ea45an%40googlegroups.com.



--
Mike Orr <slugg...@gmail.com>

Jonathan Vanasco

unread,
Aug 17, 2022, 2:26:22 PM8/17/22
to pylons-discuss
If it's read-only, i would not have it join the transaction and just create the cleanup subscriber in the @reify .  

> # Because this was in the tutorial.

I believe that is in there because of me. This pattern is used to provide access to the current request within SqlAlchemy objects and various @property or @reify decorated methods.  Without it, you must explicitly pass in a request (so no decorators) or use the `get_current_request` function which should generally be avoided.  There is a bit of discussion on it in the PR, and the cookiecutter template has many notes on it. See https://github.com/Pylons/pyramid-cookiecutter-starter/pull/111

Michael Merickel

unread,
Aug 17, 2022, 2:46:06 PM8/17/22
to pylons-...@googlegroups.com
I think it's worth noting that zope.sqlalchemy's session registration supports a "readonly" initial state, similar to active and changed that we've all harped on in the past. I'd probably just look into using that and sticking with existing patterns. If you go all-in on readonly as a pattern I think it could be a lot simpler but hey, this lets you use the existing pattern.



--

Michael

pzzcc

unread,
Aug 18, 2022, 4:36:30 AM8/18/22
to pylons-discuss
I would like to thank you for taking the time to reply and simplify things. 


yes I would like to go lower / close to metal because there is a lot of postgresql API that I would like to access and experiment with.

I don't want to fight with any abstraction layer and development time is really not an issue since this tool is used only by me. so I am not under any pressure to iterate quickly or push out a new feature to meet any demand.

I remember a few years ago taking almost a day to modify a model to return json, it was so simple but it took me a day and I wasn't really sure of the internals so i was worried that It will take me months to understand SQLALCHEMY way of doing things , while what I was doing shouldn't take even half hour to accomplish.

thats my own opinion , there is nothing wrong with SQLALCHEMY but I don't quite understand whats going on internally so I stopped.

the more I look into postgres the more I want to make a use of it is features.

Mikko Ohtamaa

unread,
Aug 18, 2022, 8:03:18 AM8/18/22
to pylons-...@googlegroups.com

Hi all,

A very interesting discussion thread!

thats my own opinion , there is nothing wrong with SQLALCHEMY but I don't quite understand whats going on internally so I stopped.

This might be a bit off-topic, but this is the weak area of SqlAlchemy. It is very brilliant engineering, but it is a very complex beast. Due to the legacy of Python documentation practices, its own documentation of reference manual is not as good as some others (e.g. Django) making SQLAlchemy harder to learn.

Nowadays I program SQLAlchemy by using StackOverflow. This is after 10 years of using SQLAlchemy. Makes the process more tolerable. However, the extra power you get from it in a big project is worth it. The project needs to be a big though, and fit nicely into the web app/CRUD style scope.

Which brings me to the offtopic questions: what are the best alternatives of SQLAlchemy in Python today - something that could be a bit easier to approach and might work better for smaller projects?

Myself, I am probably too old to start learning anything new, so I just use SQLAlchemy and then drop to raw SQL strings when I need to deal with something ORM cannot handle.

Br,
Mikko
 

Mike Orr

unread,
Aug 18, 2022, 9:16:49 AM8/18/22
to pylons-...@googlegroups.com
On Thu, Aug 18, 2022 at 5:03 AM Mikko Ohtamaa <mi...@redinnovation.com> wrote:
> Nowadays I program SQLAlchemy by using StackOverflow. This is after 10 years of using SQLAlchemy. Makes the process more tolerable. However, the extra power you get from it in a big project is worth it. The project needs to be a big though, and fit nicely into the web app/CRUD style scope.
>
> Which brings me to the offtopic questions: what are the best alternatives of SQLAlchemy in Python today - something that could be a bit easier to approach and might work better for smaller projects?

Nothing does SQLAlchemy as well as SQLAlchemy. It's much better and
more flexible than previous Python ORMs like SQLObject. However, it is
complex, and the learning curve can be high. If you introspect a table
or result object, or trace the code to see how a column type is
implemented, etc, even a simple thing has several layers of calls and
abstraction and you wonder whether it's overkill. So let me describe
how to do low-level Postges things both with SQLAlchemy and without.
I've used SQLAlchemy since ca. 2007 so I've gone through several
versions and applied it to several websites. However, my experience is
mostly in the 1.0 - 1.3 days, so I haven't migrated to the
2.0/1.4-future API yet. And I'm just writing from memory so the syntax
may not be exact.

First of all, you need an Engine and a Connection. You may want a
Transaction and an (ORM) Session. Turn on logging so you can see the
SQL statements executed: that's the key to seeing what it's doing with
Postgres. The SQL may be more elaborate than you would write; e.g.,
"SELECT `tablename`.fieldname" instead of "SELECT fieldname". Say you
want to do everything with SQL strings:

import logging
import sqlalchemy
logging.basicConfig(level=logging.INFO)
logging.getLogger("sqlalchemy.engine").setLevel(logging.INFO) #
Enable SQL logging, or use engine 'echo' argument.
t = sqlalchemy.text # Wrapper for SQL strings.
dburl = "postgresql://USERNAME:PASSWORD@HOST/DBNAME"
engine = sqlalchemy.create_engine(dburl)
with engine.connect() as conn:
# Different in 2.0: transactions, stricter text(), way of
executing query and the result object.
with conn.begin(): # Transaction. Or use 'try' block for full
commit/rollback control.
sql = t "SQLECT id, priority, my_postgres_func() AS funk FROM
tablename WHERE priority >= :pri")
params = {"pri": 5}
rslt = conn.execute(sql, params)
rows = list(result)
print(rows)
print(tuple(rows[0])
print(rows[0].funk)
# Can also insert, delete, update, create tables, define
Postgres functions, etc.

Without SQLAlchemy, you can use 'psycopg2' directly. You'd connect,
define a cursor, and do queries with the cursor, in the same spirit as
the SQL string above.

I normally define SQLAlchemy tables in any case, so that they're there
for anything I might do in the future. You can define the columns
explicitly, or use reflection to have SQLAlchemy figure it out from
the existing database. I've also gone to using a Session in most
cases, even if I'm only executing Core queries, again for flexibility.
in 2.0 there's only one way to execute both Core and ORM queries
anyway.

Ian Wilson

unread,
Aug 18, 2022, 3:10:17 PM8/18/22
to pylons-...@googlegroups.com
I guess SQLAlchemy is complicated but we are talking about a library for interacting with SQL(!) (and sometimes even mysql!).  The amount of effort that has been put into the design, the documentation, the support, the migration notes, deprecation warnings, BWC, etc. is inspiring. We are spoiled in Python land and I don't want that to go unsaid.  The 2.0 changes are going to make it even better.  The ORM loading features in it blow my mind.  You can ORM and not ORM!   Reflection!  I love the library.  Thank you zzzeek and friends!

I just about crack a gear every time I see raw SQL used in JS or some other language ecosystem.  We have a space ship right here, right now.  Why are people strapping cardboard to their arms?  I've done it before myself many years ago and all I really learned was that it makes your arms really sore.

Just my 2-cents.

- Ian

--
You received this message because you are subscribed to the Google Groups "pylons-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pylons-discus...@googlegroups.com.

Mike Orr

unread,
Aug 20, 2022, 12:56:13 PM8/20/22
to pylons-...@googlegroups.com
On Thu, Aug 18, 2022 at 12:10 PM Ian Wilson <i...@laspilitas.com> wrote:
> I just about crack a gear every time I see raw SQL used in JS or some other language ecosystem. We have a space ship right here, right now. Why are people strapping cardboard to their arms? I've done it before myself many years ago and all I really learned was that it makes your arms really sore.

That was me before Pylons and WSGI. Web frameworks were like 1980s
microcomputers: every one was monolithic and non-interoperable. I
started using minimalist frameworks where I could read the entire docs
and code in half an hour. But they were so minimalist I had to write
my own database adapter, template integration, session manager, and
authentication/authorization. One thing that drew me to Pylons and
Pyramid was I could leverage libraries written by experts, yet they
were still modular and non-monolithic, so it's relatively easy to
substitute one of the libraries if you want to.

Eldav

unread,
Aug 20, 2022, 2:37:37 PM8/20/22
to pylons-discuss
Hi everybody,

I just about crack a gear every time I see raw SQL used in JS or some other language ecosystem.  We have a space ship right here, right now.  Why are people strapping cardboard to their arms?  I've done it before myself many years ago and all I really learned was that it makes your arms really sore.

For Python, agreed, SQLAlchemy RuLeZ :)

For JS, I have yet to find a convincing ORM. Prisma looked promising, that is, *until* I tried it. There are so many SQL constructs you just can't express with it.

Even with "Raw" SQL, expressing e.g. a "WHERE col IN <param>" clause with a variable param seems to require black magick with Prisma.

So, *if* I have to write a backend function with SQL queries in JS, e.g. for Next.JS, I will use raw SQL. But I'll try to use a Python backend if that's feasible (some cloud-based start-ups are limited to JS-only environments...)

Laurent.
Reply all
Reply to author
Forward
0 new messages