I'm using hybrid_property, and would like the key of the property to be set to the attribute name, rather than the name of the getter. This is because I'm generating a getter function based on some args, rather than having the caller directly defining the getter. As a minimal example:
from __future__ import unicode_literals from sqlalchemy import create_engine, Column, Integer, String from sqlalchemy.ext.hybrid import hybrid_property from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import Session def prefixed_property(other_column, prefix): def instance_get(self): return prefix + getattr(self, other_column.key) return hybrid_property(fget=instance_get) Base = declarative_base() class Person(Base): __tablename__ = "person" id = Column(Integer, primary_key=True) name = Column(String) greeting = prefixed_property(name, "Hello ") engine = create_engine("sqlite:///:memory:") Base.metadata.create_all(engine) session = Session(engine) session.add(Person(name="Bob")) session.commit() assert session.query(Person.greeting).one() == ("Hello Bob", ) assert session.query(Person.greeting).one().greeting == "Hello Bob" # Fails with AttributeError since hybrid_property uses instance_get as the name Is there a sensible way to do this? Or am I going about the problem the wrong way? In practice, I'm using this to define properties backed by a JSON field. In case it makes any different, here's the actual use-case I have: from __future__ import unicode_literals import os from sqlalchemy import create_engine, Column, Integer from sqlalchemy.dialects.postgresql import JSONB from sqlalchemy.event import listens_for from sqlalchemy.ext.hybrid import hybrid_property from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import Session from sqlalchemy.pool import StaticPool def json_property(json_column, name, type_=None): def instance_get(self): return getattr(self, json_column.key)[name] def instance_set(self, value): json_obj = getattr(self, json_column.key) if json_obj is None: setattr(self, json_column.key, {}) getattr(self, json_column.key)[name] = value def cls_get(cls): expression = json_column[name] if type_: return expression.astext.cast(type_) else: return expression return hybrid_property(fget=instance_get, expr=cls_get, fset=instance_set) Base = declarative_base() class Person(Base): __tablename__ = "person" id = Column(Integer, primary_key=True) data = Column(JSONB, nullable=False) born = json_property(data, "born", Integer()) engine = create_engine(os.environ["TEST_DATABASE"], poolclass=StaticPool) engine.execute("SET search_path TO pg_temp") @listens_for(engine, "engine_connect") def set_search_path(connection, branch): connection.execute("SET search_path TO pg_temp") Base.metadata.create_all(engine) session = Session(engine) session.add(Person(born=1881)) session.commit() assert session.query(Person.born).one() == (1881, ) # Works fine assert session.query(Person.born).one().born == 1881 # Raises AttributeError since hybrid_property uses instance_get as the name -- SQLAlchemy - The Python SQL Toolkit and Object Relational Mapper http://www.sqlalchemy.org/ To post example code, please provide an MCVE: Minimal, Complete, and Verifiable Example. See http://stackoverflow.com/help/mcve for a full description. --- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+unsubscr...@googlegroups.com. To post to this group, send email to sqlalchemy@googlegroups.com. Visit this group at https://groups.google.com/group/sqlalchemy. For more options, visit https://groups.google.com/d/optout.