I am building a Python application that uses SQLAlchemy, and I am trying to implement a many-to-many relationship between a custom declarative base class and itself (self-referential). But I cannot get it to work. I am attaching the code down below, as well as the error traceback, in case anyone can help :) All the entities of the model already extended from this base class, and the application was working so far, in case that helps.
Thanks!!
Code (non-functional):
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from sqlalchemy import MetaData, Table
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, ForeignKey
from sqlalchemy.orm import relationship
from sqlalchemy import String
permissions = Table(
'permissions', MetaData(),
Column('origin_id', String, ForeignKey('bases.id'), primary_key=True),
Column('target_id', String, ForeignKey('bases.id'), primary_key=True)
)
class Base:
__tablename__ = 'bases'
__table_args__ = {
'mysql_engine': 'InnoDB'
}
id = Column(String, primary_key=True)
targets = relationship(
'Base',
secondary='permissions',
primaryjoin='Base.id == permissions.c.origin_id',
secondaryjoin='Base.id == permissions.c.target_id',
backref='origins'
# Reference:
# https://docs.sqlalchemy.org/en/14/orm/join_conditions.html#self-referential-many-to-many
)
Base = declarative_base(cls=Base)
Traceback:
class ContactMethod(Base):
File "/usr/local/lib/python3.8/site-packages/SQLAlchemy-1.4.23-py3.8-linux-x86_64.egg/sqlalchemy/orm/decl_api.py", line 72, in __init__
_as_declarative(reg, cls, dict_)
File "/usr/local/lib/python3.8/site-packages/SQLAlchemy-1.4.23-py3.8-linux-x86_64.egg/sqlalchemy/orm/decl_base.py", line 126, in _as_declarative
return _MapperConfig.setup_mapping(registry, cls, dict_, None, {})
File "/usr/local/lib/python3.8/site-packages/SQLAlchemy-1.4.23-py3.8-linux-x86_64.egg/sqlalchemy/orm/decl_base.py", line 177, in setup_mapping
return cfg_cls(registry, cls_, dict_, table, mapper_kw)
File "/usr/local/lib/python3.8/site-packages/SQLAlchemy-1.4.23-py3.8-linux-x86_64.egg/sqlalchemy/orm/decl_base.py", line 299, in __init__
self._scan_attributes()
File "/usr/local/lib/python3.8/site-packages/SQLAlchemy-1.4.23-py3.8-linux-x86_64.egg/sqlalchemy/orm/decl_base.py", line 511, in _scan_attributes
raise exc.InvalidRequestError(
sqlalchemy.exc.InvalidRequestError: Mapper properties (i.e. deferred,column_property(), relationship(), etc.) must be declared as @declared_attr callables on declarative mixin classes. For dataclass field() objects, use a lambda: