]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Add Mapped() support for values()
authorYossi <54272821+Apakottur@users.noreply.github.com>
Fri, 28 Nov 2025 16:04:44 +0000 (16:04 +0000)
committerYossi <54272821+Apakottur@users.noreply.github.com>
Fri, 28 Nov 2025 16:23:37 +0000 (16:23 +0000)
lib/sqlalchemy/sql/_selectable_constructors.py
lib/sqlalchemy/sql/selectable.py
test/typing/plain_files/sql/_selectable_constructors.py [new file with mode: 0644]

index 129806204bb65690309a48b8a62d1853db4eb86b..0a11688a3875294ed2381f818c4613c6d05ab886 100644 (file)
@@ -33,10 +33,12 @@ from .selectable import Values
 from ..util.typing import TupleAny
 from ..util.typing import Unpack
 
+
 if TYPE_CHECKING:
     from ._typing import _FromClauseArgument
     from ._typing import _OnClauseArgument
     from ._typing import _SelectStatementForCompoundArgument
+    from ._typing import _DMLColumnArgument
     from ._typing import _T0
     from ._typing import _T1
     from ._typing import _T2
@@ -684,7 +686,7 @@ def union_all(
 
 
 def values(
-    *columns: ColumnClause[Any],
+    *columns: _DMLColumnArgument[Any],
     name: Optional[str] = None,
     literal_binds: bool = False,
 ) -> Values:
index 48fc75e3a11b8ea0a7a963cfd93ff67cca381a48..e2872bf7bb7e945efeed3386cabc5f625ee081e2 100644 (file)
@@ -123,6 +123,7 @@ if TYPE_CHECKING:
     from ._typing import _NOT_ENTITY
     from ._typing import _OnClauseArgument
     from ._typing import _SelectStatementForCompoundArgument
+    from ._typing import _DMLColumnArgument
     from ._typing import _T0
     from ._typing import _T1
     from ._typing import _T2
@@ -3367,7 +3368,7 @@ class Values(roles.InElementRole, HasCTE, Generative, LateralFromClause):
 
     def __init__(
         self,
-        *columns: ColumnClause[Any],
+        *columns: _DMLColumnArgument[Any],
         name: Optional[str] = None,
         literal_binds: bool = False,
     ):
@@ -7117,7 +7118,6 @@ class Exists(UnaryExpression[bool]):
         self,
         fn: Callable[[Select[Unpack[TupleAny]]], Select[Unpack[TupleAny]]],
     ) -> ScalarSelect[Any]:
-
         assert isinstance(self.element, ScalarSelect)
         element = self.element.element
         if not isinstance(element, Select):
diff --git a/test/typing/plain_files/sql/_selectable_constructors.py b/test/typing/plain_files/sql/_selectable_constructors.py
new file mode 100644 (file)
index 0000000..177e639
--- /dev/null
@@ -0,0 +1,32 @@
+from sqlalchemy import update
+from sqlalchemy import values
+
+from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
+
+
+class DbBase(DeclarativeBase):
+    pass
+
+
+class MyTable(DbBase):
+    __tablename__ = "my_table"
+
+    id: Mapped[int] = mapped_column(primary_key=True)
+    name: Mapped[str]
+
+
+update_values = values(
+    MyTable.id,
+    MyTable.name,
+    name="update_values",
+).data([(1, "Alice"), (2, "Bob")])
+
+query = (
+    update(MyTable)
+    .values(
+        {
+            MyTable.name: update_values.c.name,
+        }
+    )
+    .where(MyTable.id == update_values.c.id)
+)