From: Mike Bayer Date: Sat, 28 Jan 2023 19:56:17 +0000 (-0500) Subject: Place DDLConstraintColumn Role in Mapped X-Git-Tag: rel_2_0_1~19^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4cae82d51f80c8a7e1a23b26c74b07e01059b804;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git Place DDLConstraintColumn Role in Mapped Fixed typing issue where :func:`_orm.mapped_column` objects typed as :class:`_orm.Mapped` wouldn't be accepted in schema constraints such as :class:`_schema.ForeignKey`, :class:`_schema.UniqueConstraint` or :class:`_schema.Index`. Fixes: #9170 Change-Id: I41c76d224a1fa2377de151d2a713ba3f43bd245c --- diff --git a/doc/build/changelog/unreleased_20/9170.rst b/doc/build/changelog/unreleased_20/9170.rst new file mode 100644 index 0000000000..f891c2d4bc --- /dev/null +++ b/doc/build/changelog/unreleased_20/9170.rst @@ -0,0 +1,8 @@ +.. change:: + :tags: bug, typing + :tickets: 9170 + + Fixed typing issue where :func:`_orm.mapped_column` objects typed as + :class:`_orm.Mapped` wouldn't be accepted in schema constraints such as + :class:`_schema.ForeignKey`, :class:`_schema.UniqueConstraint` or + :class:`_schema.Index`. diff --git a/lib/sqlalchemy/orm/attributes.py b/lib/sqlalchemy/orm/attributes.py index 261a633a34..cdc729f739 100644 --- a/lib/sqlalchemy/orm/attributes.py +++ b/lib/sqlalchemy/orm/attributes.py @@ -135,7 +135,6 @@ class QueryableAttribute( interfaces.PropComparator[_T], roles.JoinTargetRole, roles.OnClauseRole, - roles.DDLConstraintColumnRole, sql_base.Immutable, cache_key.SlotsMemoizedHasCacheKey, util.MemoizedSlots, diff --git a/lib/sqlalchemy/orm/base.py b/lib/sqlalchemy/orm/base.py index 331464cf80..5b6675365e 100644 --- a/lib/sqlalchemy/orm/base.py +++ b/lib/sqlalchemy/orm/base.py @@ -31,6 +31,7 @@ from ._typing import insp_is_mapper from .. import exc as sa_exc from .. import inspection from .. import util +from ..sql import roles from ..sql.elements import SQLColumnExpression from ..sql.elements import SQLCoreOperations from ..util import FastIntFlag @@ -775,6 +776,7 @@ class Mapped( SQLORMExpression[_T], ORMDescriptor[_T], _MappedAnnotationBase[_T], + roles.DDLConstraintColumnRole, ): """Represent an ORM mapped attribute on a mapped class. diff --git a/lib/sqlalchemy/orm/properties.py b/lib/sqlalchemy/orm/properties.py index baaa0291b4..9feb72e40f 100644 --- a/lib/sqlalchemy/orm/properties.py +++ b/lib/sqlalchemy/orm/properties.py @@ -47,7 +47,6 @@ from .. import util from ..sql import coercions from ..sql import roles from ..sql.base import _NoArg -from ..sql.roles import DDLConstraintColumnRole from ..sql.schema import Column from ..sql.schema import SchemaConst from ..sql.type_api import TypeEngine @@ -504,7 +503,6 @@ class MappedSQLExpression(ColumnProperty[_T], _DeclarativeMapped[_T]): class MappedColumn( - DDLConstraintColumnRole, _IntrospectsAnnotations, _MapsColumns[_T], _DeclarativeMapped[_T], diff --git a/test/ext/mypy/plain_files/mapped_column.py b/test/ext/mypy/plain_files/mapped_column.py index 14f4ad845a..26f5722a6f 100644 --- a/test/ext/mypy/plain_files/mapped_column.py +++ b/test/ext/mypy/plain_files/mapped_column.py @@ -1,7 +1,10 @@ from typing import Optional +from sqlalchemy import ForeignKey +from sqlalchemy import Index from sqlalchemy import Integer from sqlalchemy import String +from sqlalchemy import UniqueConstraint from sqlalchemy.orm import DeclarativeBase from sqlalchemy.orm import Mapped from sqlalchemy.orm import mapped_column @@ -44,9 +47,10 @@ class X(Base): c: Mapped[str] = mapped_column(nullable=True) d: Mapped[str] = mapped_column(nullable=False) - e: Mapped[Optional[str]] = mapped_column(nullable=True) + e: Mapped[Optional[str]] = mapped_column(ForeignKey(c), nullable=True) - f: Mapped[Optional[str]] = mapped_column(nullable=False) + f1 = mapped_column(Integer) + f: Mapped[Optional[str]] = mapped_column(ForeignKey(f1), nullable=False) g: Mapped[str] = mapped_column(String) h: Mapped[Optional[str]] = mapped_column(String) @@ -88,3 +92,5 @@ class X(Base): String, nullable=False, ) + + __table_args__ = (UniqueConstraint(a, b, name="uq1"), Index("ix1", c, d))