]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
proposal: remove _execute_compiled()
authorMike Bayer <mike_mp@zzzcomputing.com>
Tue, 5 Mar 2024 21:28:51 +0000 (16:28 -0500)
committerFederico Caselli <cfederico87@gmail.com>
Thu, 23 Oct 2025 19:38:15 +0000 (21:38 +0200)
this isn't used internally and only allows execute(stmt.compile())
to work, which is not something I want to support.

Since people are definitely using this [1] we might want to think about
either deprectation or having a recipe for people who really want
to still do this

[1] https://github.com/sqlalchemy/sqlalchemy/discussions/11108?converting=1

Change-Id: I5f0fe800e31aac052926cebe9206763eef9a804c

doc/build/changelog/unreleased_21/remove_compiled.rst [new file with mode: 0644]
lib/sqlalchemy/engine/base.py
lib/sqlalchemy/sql/compiler.py
test/engine/test_execute.py
test/sql/test_query.py
test/sql/test_types.py

diff --git a/doc/build/changelog/unreleased_21/remove_compiled.rst b/doc/build/changelog/unreleased_21/remove_compiled.rst
new file mode 100644 (file)
index 0000000..033478c
--- /dev/null
@@ -0,0 +1,7 @@
+.. change::
+    :tags: engine, change
+
+    The private method ``Connection._execute_compiled`` is removed.  This method may
+    have been used for some special purposes however the :class:`.SQLCompiler`
+    object has lots of special state that should be set up for an execute call,
+    which we don't support.
index c7439b57be4f2aa86c8ac1ee8d206d0a74332f24..0d8bf6f08b2b9d3446904b4c740f26563b88902e 100644 (file)
@@ -1672,56 +1672,6 @@ class Connection(ConnectionEventsTarget, inspection.Inspectable["Inspector"]):
             )
         return ret
 
-    def _execute_compiled(
-        self,
-        compiled: Compiled,
-        distilled_parameters: _CoreMultiExecuteParams,
-        execution_options: CoreExecuteOptionsParameter = _EMPTY_EXECUTION_OPTS,
-    ) -> CursorResult[Unpack[TupleAny]]:
-        """Execute a sql.Compiled object.
-
-        TODO: why do we have this?   likely deprecate or remove
-
-        """
-
-        exec_opts = compiled.execution_options.merge_with(
-            self._execution_options, execution_options
-        )
-
-        if self._has_events or self.engine._has_events:
-            (
-                compiled,
-                distilled_parameters,
-                event_multiparams,
-                event_params,
-            ) = self._invoke_before_exec_event(
-                compiled, distilled_parameters, exec_opts
-            )
-
-        dialect = self.dialect
-
-        ret = self._execute_context(
-            dialect,
-            dialect.execution_ctx_cls._init_compiled,
-            compiled,
-            distilled_parameters,
-            exec_opts,
-            compiled,
-            distilled_parameters,
-            None,
-            None,
-        )
-        if self._has_events or self.engine._has_events:
-            self.dispatch.after_execute(
-                self,
-                compiled,
-                event_multiparams,
-                event_params,
-                exec_opts,
-                ret,
-            )
-        return ret
-
     def exec_driver_sql(
         self,
         statement: str,
index e95eaa59183c406f6715029c454488fbe5793e40..38290980bf3d9f7d9cc14ab40085a26a96ebe561 100644 (file)
@@ -928,16 +928,6 @@ class Compiled:
     def _init_compiler_cls(cls):
         pass
 
-    def _execute_on_connection(
-        self, connection, distilled_params, execution_options
-    ):
-        if self.can_execute:
-            return connection._execute_compiled(
-                self, distilled_params, execution_options
-            )
-        else:
-            raise exc.ObjectNotExecutableError(self.statement)
-
     def visit_unsupported_compilation(self, element, err, **kw):
         raise exc.UnsupportedCompilationError(self, type(element)) from err
 
index 01bb1fe94b89b18a917cdb38194d0224e9eba237..17a51ad76f1e2b06364ed214e3bb8df547dacff3 100644 (file)
@@ -32,7 +32,6 @@ from sqlalchemy import util
 from sqlalchemy import VARCHAR
 from sqlalchemy.connectors.asyncio import AsyncAdapt_dbapi_module
 from sqlalchemy.engine import BindTyping
-from sqlalchemy.engine import default
 from sqlalchemy.engine.base import Connection
 from sqlalchemy.engine.base import Engine
 from sqlalchemy.pool import AsyncAdaptedQueuePool
@@ -703,39 +702,6 @@ class ExecuteTest(fixtures.TablesTest):
                 "insert into users (user_id, user_name) values (?, ?)", []
             )
 
-    @testing.only_on("sqlite")
-    def test_execute_compiled_favors_compiled_paramstyle(self):
-        users = self.tables.users
-
-        with patch.object(testing.db.dialect, "do_execute") as do_exec:
-            stmt = users.update().values(user_id=1, user_name="foo")
-
-            d1 = default.DefaultDialect(paramstyle="format")
-            d2 = default.DefaultDialect(paramstyle="pyformat")
-
-            with testing.db.begin() as conn:
-                conn.execute(stmt.compile(dialect=d1))
-                conn.execute(stmt.compile(dialect=d2))
-
-            eq_(
-                do_exec.mock_calls,
-                [
-                    call(
-                        mock.ANY,
-                        "UPDATE users SET user_id=%s, user_name=%s",
-                        (1, "foo"),
-                        mock.ANY,
-                    ),
-                    call(
-                        mock.ANY,
-                        "UPDATE users SET user_id=%(user_id)s, "
-                        "user_name=%(user_name)s",
-                        {"user_name": "foo", "user_id": 1},
-                        mock.ANY,
-                    ),
-                ],
-            )
-
     @testing.requires.ad_hoc_engines
     def test_engine_level_options(self):
         eng = engines.testing_engine(
@@ -2266,11 +2232,6 @@ class EngineEventsTest(fixtures.TestBase):
         with e1.connect() as conn:
             conn.execute(select(1))
             conn.execute(select(1).compile(dialect=e1.dialect).statement)
-            conn.execute(select(1).compile(dialect=e1.dialect))
-
-            conn._execute_compiled(
-                select(1).compile(dialect=e1.dialect), (), {}
-            )
 
     @testing.emits_warning("The garbage collector is trying to clean up")
     def test_execute_events(self):
index 5d7788fcf1cff68c9c8667e8d82e662502d44905..72b6bff738be29dc98b5c3c949c483b3f8be6b92 100644 (file)
@@ -12,7 +12,6 @@ from sqlalchemy import Integer
 from sqlalchemy import intersect
 from sqlalchemy import literal
 from sqlalchemy import literal_column
-from sqlalchemy import MetaData
 from sqlalchemy import not_
 from sqlalchemy import or_
 from sqlalchemy import select
@@ -271,29 +270,6 @@ class QueryTest(fixtures.TablesTest):
                 [],
             )
 
-    def test_compiled_execute(self, connection):
-        users = self.tables.users
-        connection.execute(users.insert(), dict(user_id=7, user_name="jack"))
-        s = (
-            select(users)
-            .where(users.c.user_id == bindparam("id"))
-            .compile(connection)
-        )
-        eq_(connection.execute(s, dict(id=7)).first()._mapping["user_id"], 7)
-
-    def test_compiled_insert_execute(self, connection):
-        users = self.tables.users
-        connection.execute(
-            users.insert().compile(connection),
-            dict(user_id=7, user_name="jack"),
-        )
-        s = (
-            select(users)
-            .where(users.c.user_id == bindparam("id"))
-            .compile(connection)
-        )
-        eq_(connection.execute(s, dict(id=7)).first()._mapping["user_id"], 7)
-
     def test_repeated_bindparams(self, connection):
         """Tests that a BindParam can be used more than once.
 
@@ -778,50 +754,6 @@ class QueryTest(fixtures.TablesTest):
             [(7, "jack"), (8, "fred")],
         )
 
-    def test_expanding_in_dont_alter_compiled(self, connection):
-        """test for issue #5048"""
-
-        class NameWithProcess(TypeDecorator):
-            impl = String
-            cache_ok = True
-
-            def process_bind_param(self, value, dialect):
-                return value[3:]
-
-        users = Table(
-            "users",
-            MetaData(),
-            Column("user_id", Integer, primary_key=True),
-            Column("user_name", NameWithProcess()),
-        )
-
-        connection.execute(
-            users.insert(),
-            [
-                dict(user_id=7, user_name="AB jack"),
-                dict(user_id=8, user_name="BE fred"),
-                dict(user_id=9, user_name="GP ed"),
-            ],
-        )
-
-        stmt = (
-            select(users)
-            .where(users.c.user_name.in_(bindparam("uname", expanding=True)))
-            .order_by(users.c.user_id)
-        )
-
-        compiled = stmt.compile(testing.db)
-        eq_(len(compiled._bind_processors), 1)
-
-        eq_(
-            connection.execute(
-                compiled, {"uname": ["HJ jack", "RR fred"]}
-            ).fetchall(),
-            [(7, "jack"), (8, "fred")],
-        )
-
-        eq_(len(compiled._bind_processors), 1)
-
     @testing.skip_if(["mssql"])
     def test_bind_in(self, connection):
         """test calling IN against a bind parameter.
index 486d4199ace3c16262253b4345f4459d5bb94e81..4d73eb9931a2f2406423afd745777361e2c475b0 100644 (file)
@@ -3115,7 +3115,7 @@ class BinaryTest(fixtures.TablesTest, AssertsExecutionResults):
         compiled = select(cast(literal(util.b("foo")), LargeBinary)).compile(
             dialect=testing.db.dialect, compile_kwargs={"literal_binds": True}
         )
-        result = connection.execute(compiled)
+        result = connection.execute(compiled.statement)
         eq_(result.scalar(), util.b("foo"))
 
     def test_bind_processor_no_dbapi(self):