From: Mike Bayer Date: Thu, 9 Jun 2022 14:57:22 +0000 (-0400) Subject: Revert "document thread safety workaround for lambda statements" X-Git-Tag: rel_1_4_38~14 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=40aeb32efb9a9680be6db3ba4ca41ba2bf5658a8;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git Revert "document thread safety workaround for lambda statements" This reverts commit f83d95085332454b700a46ab2540036dfa67363c. --- diff --git a/doc/build/core/connections.rst b/doc/build/core/connections.rst index 037ac3b580..c683c7ee9d 100644 --- a/doc/build/core/connections.rst +++ b/doc/build/core/connections.rst @@ -1442,13 +1442,11 @@ SELECTs with LIMIT/OFFSET are correctly rendered and cached. Using Lambdas to add significant speed gains to statement production -------------------------------------------------------------------- -.. deprecated:: 1.4 The lambda statement feature is being considered - for deprecation in SQLAlchemy and removal from documentation for 2.0. The - internal workings have been shown to be not thread safe during construction - for multi-lambda statements, and the overall complexity of the feature has - proven to be mostly impractical outside of a particular narrow use case - in the ORM. - +.. deepalchemy:: This technique is generally non-essential except in very performance + intensive scenarios, and intended for experienced Python programmers. + While fairly straightforward, it involves metaprogramming concepts that are + not appropriate for novice Python developers. The lambda approach can be + applied to at a later time to existing code with a minimal amount of effort. Python functions, typically expressed as lambdas, may be used to generate SQL expressions which are cacheable based on the Python code location of @@ -1482,15 +1480,11 @@ to also having closure variables, which are significant to the whole approach:: from sqlalchemy import lambda_stmt - import threading - - mutex = threading.Lock() def run_my_statement(connection, parameter): - with mutex: - stmt = lambda_stmt(lambda: select(table)) - stmt += lambda s: s.where(table.c.col == parameter) - stmt += lambda s: s.order_by(table.c.id) + stmt = lambda_stmt(lambda: select(table)) + stmt += lambda s: s.where(table.c.col == parameter) + stmt += lambda s: s.order_by(table.c.id) return connection.execute(stmt) @@ -1521,26 +1515,15 @@ objects will run and analyze the given lambda in order to calculate how it should be cached on each run, trying to detect any potential problems. Basic guidelines include: -* **For multi-threaded applications, a mutex is required when building up - statements among multiple lambdas** - - this is a discovered limitation in the implementation; while SQLAlchemy - developers hope to repair it, code examples are illustrating this - usage for now until it can be fixed. - * **Any kind of statement is supported** - while it's expected that :func:`_sql.select` constructs are the prime use case for :func:`_sql.lambda_stmt`, DML statements such as :func:`_sql.insert` and :func:`_sql.update` are equally usable:: - import threading - - mutex = threading.Lock() - def upd(id_, newname): - with mutex: - stmt = lambda_stmt(lambda: users.update()) - stmt += lambda s: s.values(name=newname) - stmt += lambda s: s.where(users.c.id==id_) + stmt = lambda_stmt(lambda: users.update()) + stmt += lambda s: s.values(name=newname) + stmt += lambda s: s.where(users.c.id==id_) return stmt with engine.begin() as conn: @@ -1552,19 +1535,15 @@ Basic guidelines include: can accommodate ORM functionality completely and used directly with :meth:`_orm.Session.execute`:: - import threading - - mutex = threading.Lock() - def select_user(session, name): - with mutex: - stmt = lambda_stmt(lambda: select(User)) - stmt += lambda s: s.where(User.name == name) + stmt = lambda_stmt(lambda: select(User)) + stmt += lambda s: s.where(User.name == name) row = session.execute(stmt).first() return row .. + * **Bound parameters are automatically accommodated** - in contrast to SQLAlchemy's previous "baked query" system, the lambda SQL system accommodates for Python literal values which become SQL bound parameters automatically.