AttributeError: type object has no attribute 'foreign_keys'

27 views
Skip to first unread message

Larry Martell

unread,
Dec 15, 2020, 7:49:02 AM12/15/20
to sqlal...@googlegroups.com
I have this model class:

class BusinessAreaContact(Base):
__tablename__ = 'BusinessAreaContact'

businessAreaID = Column(ForeignKey('BusinessArea.businessAreaID'),
primary_key=True, nullable=False)
contactEmail = Column(ForeignKey('Contact.contactEmail'),
primary_key=True, nullable=False)

If I try and delete from the table with:

session.query(BusinessAreaContact).delete()

I get:

AttributeError: type object 'BusinessAreaContact' has no attribute
'foreign_keys'

I have other models where I define FKs in the same way, and I do not
get that error with those. What makes this model different and how can
I fix this error?

Thanks!

Mike Bayer

unread,
Dec 15, 2020, 8:50:17 AM12/15/20
to noreply-spamdigest via sqlalchemy
hey there -

I don't know what that is.  Can you share the complete stack trace?  that would show me where it is misinterpreting something.  thanks!
-- 
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.


Larry Martell

unread,
Dec 15, 2020, 8:59:14 AM12/15/20
to sqlal...@googlegroups.com
File "/var/task/common/repository.py", line 74, in delete_all
res = self._session.query(model).delete()
File "/opt/python/sqlalchemy/orm/session.py", line 1558, in query
return self._query_cls(entities, self, **kwargs)
File "/opt/python/sqlalchemy/orm/query.py", line 191, in __init__
self._set_entities(entities)
File "/opt/python/sqlalchemy/orm/query.py", line 219, in _set_entities
self._set_entity_selectables(self._entities)
File "/opt/python/sqlalchemy/orm/query.py", line 250, in _set_entity_selectables
ent.setup_entity(*d[entity])
File "/opt/python/sqlalchemy/orm/query.py", line 4187, in setup_entity
self._with_polymorphic = ext_info.with_polymorphic_mappers
File "/opt/python/sqlalchemy/util/langhelpers.py", line 883, in __get__
obj.__dict__[self.__name__] = result = self.fget(obj)
File "/opt/python/sqlalchemy/orm/mapper.py", line 2141, in
_with_polymorphic_mappers
configure_mappers()
File "/opt/python/sqlalchemy/orm/mapper.py", line 3255, in configure_mappers
mapper._post_configure_properties()
File "/opt/python/sqlalchemy/orm/mapper.py", line 1950, in
_post_configure_properties
prop.init()
File "/opt/python/sqlalchemy/orm/interfaces.py", line 196, in init
self.do_init()
File "/opt/python/sqlalchemy/orm/relationships.py", line 1984, in do_init
self._setup_join_conditions()
File "/opt/python/sqlalchemy/orm/relationships.py", line 2048, in
_setup_join_conditions
self._join_condition = jc = JoinCondition(
File "/opt/python/sqlalchemy/orm/relationships.py", line 2408, in __init__
self._determine_joins()
File "/opt/python/sqlalchemy/orm/relationships.py", line 2504, in
_determine_joins
self.secondaryjoin = join_condition(
File "<string>", line 2, in join_condition
File "<string>", line 2, in _join_condition
File "/opt/python/sqlalchemy/util/deprecations.py", line 128, in warned
return fn(*args, **kwargs)
File "/opt/python/sqlalchemy/sql/selectable.py", line 932, in _join_condition
constraints = cls._joincond_scan_left_right(
File "/opt/python/sqlalchemy/sql/selectable.py", line 987, in
_joincond_scan_left_right
b.foreign_keys, key=lambda fk: fk.parent._creation_order
AttributeError: type object 'BusinessAreaContact' has no attribute
'foreign_keys'

Mike Bayer

unread,
Dec 15, 2020, 9:07:14 AM12/15/20
to noreply-spamdigest via sqlalchemy
Thanks for that.

So I think I'm going to make a small change here because I'm amazed that this is the error you're getting, for something that is likely a very common mistake and we should be checking for this.

It seems likely, as I can reproduce this exactly here, that somewhere in your model you have something like this:

class Something(...):
    # ...
    things = relationship(SomethignElse, secondary=BusinessAreaContact)

the mappers are trying to configure themselves and are tripping over that; it expects the "secondary" argument to be an instance of Table, not a mapped class.

so like:

class Something(...):
    # ...
    things = relationship(SomethignElse, secondary=BusinessAreaContact.__table__)

but again I'm amazed we aren't checking for this?   so i want to fix that now.  thanks for reporting!
-- 
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.

Larry Martell

unread,
Dec 15, 2020, 9:17:56 AM12/15/20
to sqlal...@googlegroups.com
Yes, I have:

class BusinessArea(Base):
.
.
.
Contact = relationship('Contact', secondary='BusinessAreaContact')

Is there anything I can do now to be able to proceed with my development?
> To view this discussion on the web visit https://groups.google.com/d/msgid/sqlalchemy/6a0edecd-d9b2-4442-8941-0d06c171cf4e%40www.fastmail.com.

Mike Bayer

unread,
Dec 15, 2020, 10:21:25 AM12/15/20
to noreply-spamdigest via sqlalchemy


On Tue, Dec 15, 2020, at 9:17 AM, Larry Martell wrote:
Yes, I have:

class BusinessArea(Base):
.
.
.
Contact = relationship('Contact', secondary='BusinessAreaContact')

Is there anything I can do now to be able to proceed with my development?

Ah I in fact noticed something else which is that your table name matches your class name!   OK well that explains why that's like this and....I should probably do something about that as well, ill add that to the bug I'm fixing.

For now the forms that will work are:

direct table:

Contact = relationship("Contact", secondary=BusinessAreaContact.__table__)

or use a lambda, if BusinessAreaContact is not imported yet:

Contact = relationship("Contact", secondary=lambda: BusinessAreaContact.__table__)

if you have a large application and you can't get BAC imported there or get at its table, here's a worst case workaround:

# work around SQLAlchemy issue #5774
def get_bac_table():
    from myapp import BusinessAreaContact
    return BusinessAreaContact.__table__

Contact = relationship("Contact", secondary=get_bac_table)





Larry Martell

unread,
Dec 15, 2020, 12:24:55 PM12/15/20
to sqlal...@googlegroups.com
On Tue, Dec 15, 2020 at 10:21 AM Mike Bayer <mik...@zzzcomputing.com> wrote:
>
>
>
> On Tue, Dec 15, 2020, at 9:17 AM, Larry Martell wrote:
>
> Yes, I have:
>
> class BusinessArea(Base):
> .
> .
> .
> Contact = relationship('Contact', secondary='BusinessAreaContact')
>
> Is there anything I can do now to be able to proceed with my development?
>
>
> Ah I in fact noticed something else which is that your table name matches your class name! OK well that explains why that's like this and....I should probably do something about that as well, ill add that to the bug I'm fixing.
>
> For now the forms that will work are:
>
> direct table:
>
> Contact = relationship("Contact", secondary=BusinessAreaContact.__table__)
>
> or use a lambda, if BusinessAreaContact is not imported yet:
>
> Contact = relationship("Contact", secondary=lambda: BusinessAreaContact.__table__)


Thanks! That worked for me.
Reply all
Reply to author
Forward
0 new messages