It looks like I can keep the @declared_attr by using
 "inherit_condition": cls.node_id == cls.__mro__[1].node_id

The __mro__[1] gets the leftmost (or only) parent class. As long as I
make sure that it the inheritance tree (and I wasn't planning on
multiple inheritance here) I should be ok.

On 9/3/20 10:25 AM, Mike Bayer wrote:
> yup that was the idea
>
>
> On Thu, Sep 3, 2020, at 10:24 AM, Richard Damon wrote:
>> I have a large number (around a dozen or more, and likely to grow) of
>> derived classes, so I was hoping to cut down repetition with the
>> @declared_attr.
>> So, 3rd (or farther) derived classes need the inherit_condition to point
>> to their immediate base. That does seem to remove the warning.
>>
>> On 9/3/20 9:58 AM, Mike Bayer wrote:
>> > you might be able to use the declared_attr __mapper__ but you would
>> > need to omit that erroneous inherit condition if the class is
>> > "Name".   IMO it would be easier to follow and understand by simply
>> > using explicit __mapper_args__ on each class but this depends on what
>> > you're doing.
>> >
>> >
>> >
>> > On Thu, Sep 3, 2020, at 7:24 AM, Richard Damon wrote:
>> >> I've tried taking my code and changing the ForeignKey to be to
>> Node, and
>> >> that doesn't change the Warning.
>> >> Is the problem trying to DRY with the @declared_attr __mapper__?
>> >>
>> >> On 9/2/20 11:29 PM, Mike Bayer wrote:
>> >> > well you are giving Name an inherit condition that conflicts
>> with how
>> >> > you set up the foreign key. 
>> >> >
>> >> > Name.node_id FKs to Property.node_id
>> >> >
>> >> > but then inherit condition is Name.node_id -> Node.node_id
>> >> >
>> >> > There seems to be a little unsmoothness to actually being able to
>> >> > configure it that way, that is, skipping over Property.node_id,
>> but in
>> >> > this case your FKs make it clear what you're going for which is the
>> >> > "normal' setup of Name->Property->Node so you can remove "inherit
>> >> > condition" from Name and it works fine:
>> >> >
>> >> > class Name(Property):
>> >> >     __tablename__ = 'Name'
>> >> >
>> >> >     node_id = Column(Integer, ForeignKey("Property.node_id"),
>> >> > primary_key=True)
>> >> >
>> >> >     __mapper_args__ = {
>> >> >         "polymorphic_identity": "Name",
>> >> >     }
>> >> >
>> >> >
>> >> > or set it:
>> >> >
>> >> > class Name(Property):
>> >> >     __tablename__ = 'Name'
>> >> >
>> >> >     node_id = Column(Integer, ForeignKey("Property.node_id"),
>> >> > primary_key=True)
>> >> >
>> >> >     __mapper_args__ = {
>> >> >         "polymorphic_identity": "Name",
>> >> >         "inherit_condition": node_id == Property.node_id,
>> >> >     }
>> >> >
>> >> >
>> >> >
>> >> > On Wed, Sep 2, 2020, at 10:08 PM, Richard Damon wrote:
>> >> >> Here is the code, note in all cases node_id  are foreign
>> >> key/primary_key
>> >> >> to a primary_key down the chain:
>> >> >>
>> >> >>
>> >> >> class Base:
>> >> >>     """Base Class for SQLAlchemy ORM Classes"""
>> >> >>     @declared_attr
>> >> >>     def __tablename__(cls):
>> >> >>         """Default the Table Name to the Class Name"""
>> >> >>         return cls.__name__
>> >> >>
>> >> >> Base = declarative_base(cls=Base)
>> >> >>
>> >> >> class Node(Base):
>> >> >>     """Class repesents the base of the User Data types."""
>> >> >>     node_id = Column(Integer, primary_key=True)
>> >> >>     type_name = Column(String(255), nullable=False)  # todo should
>> >> come
>> >> >> from type_id
>> >> >>
>> >> >>     @declared_attr
>> >> >>     def __mapper_args__(cls):
>> >> >>         if cls.__name__ == 'Node' :
>> >> >>             __mapper_args__ = {
>> >> >>                 'polymorphic_identity': 'Node',
>> >> >>                 'polymorphic_on': cls.type_name,
>> >> >>             }
>> >> >>         else:
>> >> >>             __mapper_args__ = {
>> >> >>                 'polymorphic_identity': cls.__tablename__,
>> >> >>                 "inherit_condition": cls.node_id == Node.node_id
>> >> >>             }
>> >> >>         return __mapper_args__
>> >> >>
>> >> >> class Property(Node):
>> >> >>     node_id = Column(Integer, ForeignKey('Node.node_id'),
>> >> >> primary_key=True)
>> >> >>     ref_id = Column(Integer, ForeignKey('Node.node_id'))
>> >> >>
>> >> >> class Name(Property):
>> >> >>     node_id = Column(Integer, ForeignKey('Property.node_id'),
>> >> >> primary_key=True)
>> >> >>
>> >> >>
>> >> >> On 9/2/20 9:39 PM, Mike Bayer wrote:
>> >> >> > there's an FAQ entry, a little bit dated but the general idea is
>> >> still
>> >> >> > there, at:
>> >> >> >
>> >> >>
>> >>
>> > 
>> >https://docs.sqlalchemy.org/en/13/faq/ormconfiguration.html#i-m-getting-a-warning-or-error-about-implicitly-combining-column-x-under-attribute-y
>> >> >> >
>> >> >> > for joined table inheritance, where Name(Node) -> node_id are
>> FK ->
>> >> >> > PK, the warning isn't emitted.  so please share the mapping
>> if it is
>> >> >> > doing this when it shouldnt.
>> >> >> >
>> >> >> >
>> >> >> > On Wed, Sep 2, 2020, at 9:08 PM, Richard Damon wrote:
>> >> >> >> I am getting the following error:
>> >> >> >>
>> >> >> >> SAWarning: Implicitly combining column Node.node_id with column
>> >> >> >> Name.node_id under attribute 'node_id'.  Please configure one
>> >> or more
>> >> >> >> attributes for these same-named columns explicitly.
>> >> >> >>
>> >> >> >> In my case I am using poymorphic classes by joining with the
>> >> ORM. Node
>> >> >> >> is the base of the hierarchy (derived from declarative_base),
>> >> then I
>> >> >> >> have a class Property derived from it, and a class Name derived
>> >> from
>> >> >> >> Property. Each class has a primary_key named node_id, with a
>> >> >> foreign key
>> >> >> >> constraint one step done the hierarchy. I have also tried making
>> >> >> all the
>> >> >> >> Foreign key constraints point to Node.node_id and it doesn't
>> make a
>> >> >> >> difference.
>> >> >> >>
>> >> >> >> It is just a warning, and the lookup does seem to make the
>> double
>> >> >> join,
>> >> >> >> so it doesn't seem to be a big problem, but it seems it want
>> me to
>> >> >> >> configure something for these, but I am not sure what.
>> >> >> >>
>> >> >> >> Two level inheritance is working just fine, it is just where it
>> >> >> hits the
>> >> >> >> 3rd level that it seems to want something explicit.
>> >> >> >>
>> >> >> >> -- 
>> >> >> >> Richard Damon
>> >> >>
>> >> >>
>> >> >> -- 
>> >> >> Richard Damon
>> >>
>> >> -- 
>> >> Richard Damon
>> >>

-- 
Richard Damon

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/sqlalchemy/58a7b1da-3965-f2ce-24d4-f92f37ccea1c%40Damon-Family.org.

Reply via email to