У меня есть две таблицы со связью «многие ко многим», поэтому между ними есть таблица соединения. Они определяются следующим образом
from sqlalchemy import String, Integer, Boolean
from sqlalchemy.orm import mapped_column, relationship
from root.db.ModelBase import ModelBase
class Module(ModelBase):
__tablename__ = 'module'
pk = mapped_column(Integer, primary_key=True)
description = mapped_column(String)
is_active = mapped_column(Boolean)
name = mapped_column(String, unique=True, nullable=False)
ngen_cal_active = mapped_column(String)
groups = relationship("ModuleGroup", secondary="module_group_member", back_populates="modules", lazy="joined")
---
from sqlalchemy import String, Integer, Boolean
from sqlalchemy.orm import mapped_column, relationship
from root.db.ModelBase import ModelBase
class ModuleGroup(ModelBase):
__tablename__ = 'module_group'
pk = mapped_column(Integer, primary_key=True)
description = mapped_column(String)
is_active = mapped_column(Boolean)
name = mapped_column(String, unique=True, nullable=False)
modules = relationship("Module", secondary="module_group_member", back_populates="groups", lazy="joined")
---
from sqlalchemy import String, Integer, Boolean, ForeignKey
from sqlalchemy.orm import mapped_column
from root.db.ModelBase import ModelBase
class ModuleGroupMember(ModelBase):
__tablename__ = 'module_group_member'
description = mapped_column(String)
is_active = mapped_column(Boolean)
module_pk = mapped_column(ForeignKey('module.pk'), primary_key=True,)
module_group_pk = mapped_column(ForeignKey('module_group.pk'), primary_key=True)
Если я сделаю такой запрос
query = select(Module).where(Module.name == 'Module3') # type: ignore
results = session.execute(query).unique().all()
print('results', results)
Похоже, что это работает (хотя я не знаю, почему это заставляет меня использовать unique(), поскольку результат должен быть только 1)
В результате , я вижу объект groups, который определяется отношением, поэтому все работает нормально.
Однако, если я хочу получить только имя и связанные группы, Я пробовал что-то вроде этого:
query = select(Module.name, Module.groups).where(Module.name == 'Module3') # type: ignore
и я получаю эту ошибку SAWarning: оператор SELECT имеет декартово произведение между элементом(ами) FROM "module_group", "module_group_member_1" и элементом FROM "module". Примените условия соединения между каждым элементом для разрешения.
Я не уверен, в чем проблема. Я думал, что SQLAlchemy позаботится обо всех соединениях, которые необходимо выполнить.
Что мне действительно нужно, так это получить все имена и группы для каждого модуля
query = select(Module.name, Module.groups)
Подробнее здесь: https://stackoverflow.com/questions/786 ... sqlalchemy