Hi, I have this case where I want to be able to access a hybrid_property that points to a related model which is further filtered using a cte (utilizing a Transformer <http://docs.sqlalchemy.org/en/latest/orm/extensions/hybrid.html#building-transformers>) without having to trigger additional database requests. So what I'm trying to achieve looks something like this:
# Python code customers = session.query(Customer).with_transformation(Customer. latest_sku_shipment.cte).all() # Jinja2 code {% for customer in customers %} <h1>{{ customer.name }}</h1> <p>Latest shipment, {{ customer.latest_sku_shipment.shipment_date }}, was sent to customer on {{ customer.latest_sku_shipment.apa }}</p> {% endfor %} Here's an example I've built that shows that it tries to access the regular property. Is there any way that it can get the data from the query that has already been executed? import sqlalchemy as sa from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.ext import hybrid Base = declarative_base() Session = sa.orm.sessionmaker() class CustomerLatestShipmentTransformer(hybrid.Comparator): @property def cte(self): def transform(q): subq = ( q.session.query( ProductSKUShipment.customer_id, ProductSKUShipment.shipment_date, ProductSKUShipment.order_no, ) .distinct(ProductSKUShipment.customer_id) # Postgres specific .order_by( ProductSKUShipment.customer_id, ProductSKUShipment.shipment_date.desc(), ) ) cte = subq.cte() return q.outerjoin(cte, cte.c.customer_id == Customer.id) return transform class Customer(Base): __tablename__ = 'customer' id = sa.Column(sa.Integer, primary_key=True) no = sa.Column(sa.Text, nullable=False) name = sa.Column(sa.Text, nullable=False) def __repr__(self): return '<{no}: {name}>'.format(**vars(self)) @hybrid.hybrid_property def latest_sku_shipment(self): # sess = sa.orm.object_session(self) # return ( # sess.query(ProductSKUShipment) # .filter_by(customer_id=self.id) # .order_by(ProductSKUShipment.shipment_date.desc()) # .first() # ) raise RuntimeError('I want to be loaded from my query!') @latest_sku_shipment.comparator def latest_sku_shipment(cls): return CustomerLatestShipmentTransformer(cls) class ProductSKUShipment(Base): __tablename__ = 'productskushipment' def __repr__(self): return '<{sku} {order_no} ({shipment_date})>'.format(**vars(self)) id = sa.Column(sa.Integer, primary_key=True) sku = sa.Column(sa.Text, unique=True) quantity = sa.Column(sa.Integer, nullable=False) order_no = sa.Column(sa.Text, nullable=False) shipment_date = sa.Column(sa.DateTime(timezone=True), nullable=False) customer_id = sa.Column( sa.Integer, sa.ForeignKey(Customer.id, ondelete='CASCADE'), nullable=False) customer = sa.orm.relationship( Customer, backref=sa.orm.backref('sku_shipments', passive_deletes='all'), ) customer = Customer( no='123', name='My customer', ) sku_shipment = ProductSKUShipment( customer=customer, order_no='12345', sku='20090-100', quantity=1, shipment_date='2015-01-01 08:34', ) sku_shipment_2 = ProductSKUShipment( customer=customer, order_no='12345', sku='10570-900', quantity=1, shipment_date='2016-02-19 13:03', ) engine = sa.create_engine('postgresql://localhost/cachedproptest') Session.configure(bind=engine) Base.metadata.create_all(bind=engine) session = Session() session.add(customer) session.flush() q = ( session.query(Customer) .with_transformation(Customer.latest_sku_shipment.cte) # .options(sa.orm.joinedload('latest_sku_shipment')) ) for customer in q: print(customer.latest_sku_shipment) -- 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.