declared_attr.cascading does not warn / error for non-mixin use

Issue #3847 resolved
Mike Bayer repo owner created an issue

use declared_attr.cascading on a non mixin, the "cascading" is ignored and it's only called once, totally confusing:

from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.declarative import declared_attr

Base = declarative_base()


class A(Base):
    __tablename__ = 'a'
    id = Column(Integer, primary_key=True)

    @declared_attr.cascading
    def foo(cls):
        if cls.__name__ == 'A':
            return Column(String)
        else:
            return Column(Integer)

class B(A):
    __tablename__ = 'b'
    id = Column(Integer, ForeignKey('a.id'), primary_key=True)


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

output:

CREATE TABLE a (
    id INTEGER NOT NULL, 
    foo VARCHAR, 
    PRIMARY KEY (id)
)


2016-11-07 20:35:49,091 INFO sqlalchemy.engine.base.Engine ()
2016-11-07 20:35:49,091 INFO sqlalchemy.engine.base.Engine COMMIT
2016-11-07 20:35:49,092 INFO sqlalchemy.engine.base.Engine 
CREATE TABLE b (
    id INTEGER NOT NULL, 
    PRIMARY KEY (id), 
    FOREIGN KEY(id) REFERENCES a (id)
)

this should ideally either work or raise an error, though for now a warning is likely the best we can do.

Comments (2)

  1. Mike Bayer reporter

    Warn when declared_attr.cascading detected on mapped class

    A warning is emitted if the :attr:.declared_attr.cascading modifier is used with a declarative attribute that is itself declared on a class that is to be mapped, as opposed to a declarative mixin class or __abstract__ class. The :attr:.declared_attr.cascading modifier currently only applies to mixin/abstract classes.

    Also add a test for @declared_attr.cascading when used on an attribute on abstract.

    Change-Id: Ib1b9dbe373e8be1cf24eadfed224a8988b3cd95d Fixes: #3847

    → <<cset 4e1f5377d1c5>>

  2. Log in to comment