#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, и он должен работать нормально.