behavior of declared_attr and column_property in a mixin doesn't correspond with documentation

Issue #3719 closed
Julius Yang created an issue

I'm trying to make this example work:

http://docs.sqlalchemy.org/en/rel_1_0/orm/extensions/declarative/mixins.html#mixing-in-deferred-column-property-and-other-mapperproperty-classes

This code returns None instead of the expected 15.

from sqlalchemy import Column, create_engine, Integer
from sqlalchemy.ext.declarative import declarative_base, declared_attr
from sqlalchemy.orm import column_property

engine = create_engine('sqlite://')
Base = declarative_base(engine)

class SomethingMixin(object):
    x = Column(Integer)
    y = Column(Integer)

    @declared_attr
    def x_plus_y(cls):
        return column_property(cls.x + cls.y)

class Something(SomethingMixin, Base):
    __tablename__ = "something"

    id = Column(Integer, primary_key=True)

foo = Something()
foo.x = 10
foo.y = 5
print foo.x_plus_y

I'm using SQLAlchemy 1.0.13. My use case: I have several classes with a latitude and longitude coordinate which I want to represent as a geoalchemy2 WKBElement internally, but as lat/long floats externally, so a getter on the mixin needs to convert.

Comments (1)

  1. Mike Bayer repo owner

    no bug is illustrated here. column_property() indicates a SQL expression that will be invoked when the value is loaded from the database. the example does not illustrate a persistent object. Make it persistent and the value is loaded from the database:

    Base.metadata.create_all(engine)
    from sqlalchemy.orm import Session
    s = Session(engine)
    s.add(foo)
    s.flush()
    print foo.x_plus_y
    

    if you're looking for an in-Python calculated value you probably want a hybrid.

  2. Log in to comment