AbstractConcreteBase and query_expression()

10 views
Skip to first unread message

Benjamin Beguin

unread,
Mar 25, 2020, 12:30:23 PM3/25/20
to sqlalchemy
Hi there,

I'm facing an issue with the use of AbstractConcreteBase class and a @declarred_attr returning a query_expression()


class A(AbstractConcreteBase, Base):
   
@declared_attr
   
def foo(cls):
       
return query_expression()


class B(A):
 
...


class C(A):
 
...


objects
= db.session.query(A).options(with_expression(A.foo, my_expression)).all()



B and C objects returned have the property foo but it is None
The generated SQL query returns a value for the expression but the mapping seems to be not effective 

Am I doing something wrong ?

Mike Bayer

unread,
Mar 25, 2020, 1:24:40 PM3/25/20
to noreply-spamdigest via sqlalchemy
I don't really know, because AbstractConcreteBase works pretty poorly and it's better to use other patterns.

Try this workaround, which I have no idea if it helps in this case:

class A(...):

    # ...


    @classmethod
    def __declare_last__(cls):
        cls.__mapper__.with_polymorphic = ("*", cls.__mapper__.local_table)


otherwise provide a more complete example and I'll try to diagnose why it doesnt work for this case.
--
SQLAlchemy -
The Python SQL Toolkit and Object Relational Mapper
 
 
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+...@googlegroups.com.

Mike Bayer

unread,
Apr 9, 2020, 12:09:32 PM4/9/20
to noreply-spamdigest via sqlalchemy
I'm not able to reproduce the issue you describe.  Below is an MCVE, can you please modify it to show the failure you are getting?   The .foo attribute on B is returned:

from sqlalchemy import Column
from sqlalchemy import create_engine
from sqlalchemy import Integer
from sqlalchemy import String
from sqlalchemy.ext.declarative import AbstractConcreteBase
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.declarative import declared_attr
from sqlalchemy.orm import configure_mappers
from sqlalchemy.orm import query_expression
from sqlalchemy.orm import Session
from sqlalchemy.orm import with_expression


Base = declarative_base()


class A(AbstractConcreteBase, Base):
    @declared_attr
    def foo(cls):
        return query_expression()


class B(A):
    __tablename__ = "b"

    id = Column(Integer, primary_key=True)

    data = Column(String(50))

    __mapper_args__ = {"polymorphic_identity": "b"}


class C(A):
    __tablename__ = "c"

    id = Column(Integer, primary_key=True)
    __mapper_args__ = {"polymorphic_identity": "c"}


configure_mappers()

e = create_engine("sqlite://", echo=True)
Base.metadata.create_all(e)

session = Session(e)

session.add(B(id=1, data='b data'))
session.commit()

b1 = session.query(A).options(with_expression(A.foo, B.data + ' hi')).all()[0]
assert b1.foo == "b data hi"







On Wed, Mar 25, 2020, at 12:30 PM, Benjamin Beguin wrote:
Reply all
Reply to author
Forward
0 new messages