1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
from datetime import datetime
import typing
from sqlalchemy import DateTime
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 declared_attr
from sqlalchemy.orm import Mapped
from sqlalchemy.orm import mapped_column
from sqlalchemy.orm import MappedClassProtocol
from sqlalchemy.sql.schema import PrimaryKeyConstraint
class Base(DeclarativeBase):
pass
class Employee(Base):
__tablename__ = "employee"
id = mapped_column(Integer, primary_key=True)
name = mapped_column(String(50))
type = mapped_column(String(20))
__mapper_args__ = {
"polymorphic_on": type,
"polymorphic_identity": "employee",
}
__table_args__ = (
Index("my_index", name, type),
UniqueConstraint(name),
PrimaryKeyConstraint(id),
{"prefix": []},
)
class Engineer(Employee):
__mapper_args__ = {
"polymorphic_identity": "engineer",
}
@declared_attr
def start_date(cls) -> Mapped[datetime]:
"Start date column, if not present already."
assert Employee.__table__ is not None
return getattr(
Employee.__table__.c,
"start date",
mapped_column("start date", DateTime),
)
class Manager(Employee):
__mapper_args__ = {
"polymorphic_identity": "manager",
}
@declared_attr
def start_date(cls) -> Mapped[datetime]:
"Start date column, if not present already."
assert Employee.__table__ is not None
return getattr(
Employee.__table__.c,
"start date",
mapped_column("start date", DateTime),
)
def do_something_with_mapped_class(
cls_: MappedClassProtocol[Employee],
) -> None:
# EXPECTED_TYPE: Select[Any]
reveal_type(cls_.__table__.select())
# EXPECTED_TYPE: Mapper[Employee]
reveal_type(cls_.__mapper__)
# EXPECTED_TYPE: Employee
reveal_type(cls_())
do_something_with_mapped_class(Manager)
do_something_with_mapped_class(Engineer)
if typing.TYPE_CHECKING:
# EXPECTED_TYPE: InstrumentedAttribute[datetime]
reveal_type(Engineer.start_date)
# EXPECTED_TYPE: InstrumentedAttribute[datetime]
reveal_type(Manager.start_date)
|