How to properly inherit declarative __table_args__?

791 views
Skip to first unread message

Russell Warren

unread,
Mar 21, 2018, 12:07:03 AM3/21/18
to sqlalchemy
I'm having trouble with SQLAlchemy throwing the warning "Unmanaged access of declarative attribute" when I try and inherit `__table_args__` with declarative.

I've been through the docs here:

... but the examples provided do not include a base class whose `__table_args__` can be simply inherited (ie: used as-is without needing to redefine `__table_args__` in the subclass).

I've been through the code and see why the warning is thrown (the class doesn't have a `_sa_class_manager` property bolted on yet), but I can't tell if this is something I can just ignore or not.  It currently seems like it can't be ignored since I'm having some weird problems around this code (still under investigation), but I'd like to know if there is some way to safely prevent this warning while achieving the desired inheritance. If it *is* actually ignorable, I've gone as far as considering temporarily hacking on a `_sa_class_manager` property to suppress the warning, but yuck.

Below is a small example of what I'm talking about.  The `_BaseTableSetup_MIXIN` class sets up some common table definitions. Foo and Bar use them outright via simple inheritance. Baz tries to extend the `__table_args__`, but runs into the warning when accessing `__table_args__` on the parent mixin.

Am I doing something wrong?
How can this be done properly?
Is ignoring the warning a bad idea?

###
# sample code

class _BaseTableSetup_MIXIN(object):
    a = Column(Integer)
    @declared_attr  # so subclasses
    def __table_args__(cls):
        # all derived classes/tables must have the unique constraint (but should
        # also be free to add more)
        return (UniqueConstraint("a"), )

class Foo(ORMBase, _BaseTableSetup_MIXIN):
    # This class defines no extra __table_args
    b = Column(Integer)

class Bar(ORMBase, _BaseTableSetup_MIXIN):
    # This class also defines no extra __table_args
    c = Column(Integer)

class Baz(ORMBase, _BaseTableSetup_MIXIN):
    # This class needs the full base setup, plus additional __table_args__
    d = Column(Integer)
    @declared_attr
    def __table_args__(cls):
        ret = list(_BaseTableSetup_MIXIN.__table_args__) # WARNING THROWN HERE!
        ret.append(UniqueConstraint("d"))
        return tuple(ret)

###

Mike Bayer

unread,
Mar 21, 2018, 9:44:32 AM3/21/18
to sqlal...@googlegroups.com
On Wed, Mar 21, 2018 at 12:07 AM, Russell Warren <ru...@perspexis.com> wrote:
> I'm having trouble with SQLAlchemy throwing the warning "Unmanaged access of
> declarative attribute" when I try and inherit `__table_args__` with
> declarative.

this is not a covered use case.

Looking at the commit for that warning, it's not clear this is coming
from a specific user case that was reported, just that normally a
@declared_attr is not supposed to be accessed outside of setting up a
mapping, and the _sa_declared_attr_reg is in fact designed to only be
present within the declarative mapping process, to hold onto the value
of the declared attr so that we dont call it more than once.

Basically there have been cases in the past where some declarative
setup returns a Column object, then they do meaningful things with
that Column (like add it to other mapping configurations), then it
gets replaced later by another Column because the declared attr was
called again and the mappings blow up. That's what the registry is
meant to fix (here is the example of that:
https://bitbucket.org/zzzeek/sqlalchemy/issues/3149/mixin_column-to-provide-more-context-for).
But the registry fixes that. the warning is showing itself to be
overkill here. so let's take it out
> --
> 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+...@googlegroups.com.
> To post to this group, send email to sqlal...@googlegroups.com.
> Visit this group at https://groups.google.com/group/sqlalchemy.
> For more options, visit https://groups.google.com/d/optout.

Mike Bayer

unread,
Mar 21, 2018, 9:52:34 AM3/21/18
to sqlal...@googlegroups.com

Russell Warren

unread,
Mar 21, 2018, 1:48:36 PM3/21/18
to sqlalchemy
but the warning is safe to ignore in any case

Perfect. Thanks for the clarification and the backing detail.  We'll just ignore the warning until that change comes in.
Reply all
Reply to author
Forward
0 new messages