sqlalchemy.exc.InvalidRequestError: Mapper ‘сопоставленный класс Room-> rooms’ не имеет свойства ‘rooms’

#python #sqlalchemy

#python #sqlalchemy

Вопрос:

sqlalchemy для конфигурации отношений «многие ко многим»

Я использую ассоциативный объект sqlalchemy и читаю документы https://docs.sqlalchemy.org/en/13/orm/basic_relationships.html#association-object

Логические: room has_man tags

room.py

 from crud import room
from sqlalchemy import Column, BigInteger, String, Integer
from sqlalchemy.orm import relationship
from sqlalchemy.sql.schema import ForeignKey
from db.base_class import Base

class Room(Base):
    __tablename__ = "rooms"

    id = Column(BigInteger, primary_key=True, index=True)
    user_id = Column(BigInteger, index=True, nullable=False)
    title = Column(String, nullable=False)
    desc = Column(String, nullable=True)

    tags = relationship('RoomTag', back_populates="room")
 

tag.py

 from sqlalchemy import Column, BigInteger, String
from sqlalchemy.orm import relationship
from db.base_class import Base


class Tag(Base):
    __tablename__ = "tags"

    id = Column(BigInteger, primary_key=True, index=True)
    name = Column(String, nullable=False)
    rooms = relationship('RoomTag', back_populates='tag')
 

room_tag.py

 from sqlalchemy import Column, BigInteger, String
from sqlalchemy.sql.schema import ForeignKey
from sqlalchemy.orm import relationship
from db.base_class import Base


class RoomTag(Base):
    __tablename__ = "room_tags"

    id = Column(BigInteger, primary_key=True, index=True)
    tag_id = Column(BigInteger, ForeignKey('tags.id'), primary_key=True)
    room_id = Column(BigInteger, ForeignKey('rooms.id'), primary_key=True)
    room = relationship('Room', back_populates="rooms")
    tag = relationship('Tag', back_populates="tags")
 

но сообщение об ошибке

 File "./crud/base.py", line 28, in get
    return db_session.query(self.model).filter(self.model.id == id).first()
  File "/Users/lidashuang/Projects/starservices/venv/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 1584, in query
    return self._query_cls(entities, self, **kwargs)
  File "/Users/lidashuang/Projects/starservices/venv/lib/python3.9/site-packages/sqlalchemy/orm/query.py", line 199, in __init__
    self._set_entities(entities)
  File "/Users/lidashuang/Projects/starservices/venv/lib/python3.9/site-packages/sqlalchemy/orm/query.py", line 227, in _set_entities
    self._set_entity_selectables(self._entities)
  File "/Users/lidashuang/Projects/starservices/venv/lib/python3.9/site-packages/sqlalchemy/orm/query.py", line 258, in _set_entity_selectables
    ent.setup_entity(*d[entity])
  File "/Users/lidashuang/Projects/starservices/venv/lib/python3.9/site-packages/sqlalchemy/orm/query.py", line 4292, in setup_entity
    self._with_polymorphic = ext_info.with_polymorphic_mappers
  File "/Users/lidashuang/Projects/starservices/venv/lib/python3.9/site-packages/sqlalchemy/util/langhelpers.py", line 883, in __get__
    obj.__dict__[self.__name__] = result = self.fget(obj)
  File "/Users/lidashuang/Projects/starservices/venv/lib/python3.9/site-packages/sqlalchemy/orm/mapper.py", line 2158, in _with_polymorphic_mappers
    configure_mappers()
  File "/Users/lidashuang/Projects/starservices/venv/lib/python3.9/site-packages/sqlalchemy/orm/mapper.py", line 3280, in configure_mappers
    mapper._post_configure_properties()
  File "/Users/lidashuang/Projects/starservices/venv/lib/python3.9/site-packages/sqlalchemy/orm/mapper.py", line 1967, in _post_configure_properties
    prop.init()
  File "/Users/lidashuang/Projects/starservices/venv/lib/python3.9/site-packages/sqlalchemy/orm/interfaces.py", line 197, in init
    self.do_init()
  File "/Users/lidashuang/Projects/starservices/venv/lib/python3.9/site-packages/sqlalchemy/orm/relationships.py", line 2080, in do_init
    self._generate_backref()
  File "/Users/lidashuang/Projects/starservices/venv/lib/python3.9/site-packages/sqlalchemy/orm/relationships.py", line 2385, in _generate_backref
    self._add_reverse_property(self.back_populates)
  File "/Users/lidashuang/Projects/starservices/venv/lib/python3.9/site-packages/sqlalchemy/orm/relationships.py", line 2001, in _add_reverse_property
    other = self.mapper.get_property(key, _configure_mappers=False)
  File "/Users/lidashuang/Projects/starservices/venv/lib/python3.9/site-packages/sqlalchemy/orm/mapper.py", line 2065, in get_property
    util.raise_(
  File "/Users/lidashuang/Projects/starservices/venv/lib/python3.9/site-packages/sqlalchemy/util/compat.py", line 178, in raise_
    raise exception
sqlalchemy.exc.InvalidRequestError: Mapper 'mapped class Room->rooms' has no property 'rooms'
 

Ответ №1:

room.py

 class Room(Base):
    __tablename__ = "rooms"
 
    tags = relationship('Tag', secondary='room_tags', back_populates="rooms")

 
 class Tag(Base):
    __tablename__ = "tags"

    id = Column(BigInteger, primary_key=True, index=True)
    name = Column(String, nullable=False)
    rooms = relationship('Room', secondary='room_tags', back_populates="tags")

 
 
class RoomTag(Base):
    __tablename__ = "room_tags"

    id = Column(BigInteger, primary_key=True, index=True)
    tag_id = Column(BigInteger, ForeignKey('tags.id'), primary_key=True)
    room_id = Column(BigInteger, ForeignKey('rooms.id'), primary_key=True)

 

Комментарии:

1. Этот ответ создает таблицу ссылок с ПЕРВИЧНЫМ КЛЮЧОМ (id, tag_id, room_id), что, я думаю, вызовет проблемы с производительностью поиска, поскольку столбец id обычно не является частью запроса. Вы можете удалить столбец id, и он должен работать нормально.