SQLAlchemy Отношение «многие ко многим» на одной таблице

У меня есть модель SQLAlchemy, настроенная в моем приложении, которая должна имитировать функциональность «последователей» в Twitter, т.е. пользователи имеют отношения «многие ко многим» с каждым из них (как последователи, так и последующие). Таблицы структурированы следующим образом (sa – модуль sqlalchemy):

t_users = sa.Table("users", meta.metadata, sa.Column("id", sa.types.Integer, primary_key=True), sa.Column("email", sa.types.String(320), unique=True, nullable=False), ...etc... ) t_follows = sa.Table("follows", meta.metadata, sa.Column("id", sa.types.Integer, primary_key=True), sa.Column("follower_id", sa.types.Integer, sa.ForeignKey('users.id'), nullable=False), sa.Column("followee_id", sa.types.Integer, sa.ForeignKey('users.id'), nullable=False) ) 

Однако я столкнулся с небольшим препятствием, пытаясь использовать orm.mapper для создания этих отношений, поскольку вторичная таблица ссылается на ту же основную таблицу в обоих направлениях. Как я могу сопоставить это отношение с ORM?

2 Solutions collect form web for “SQLAlchemy Отношение «многие ко многим» на одной таблице”

В этом случае вы должны primaryjoin писать primaryjoin и secondaryjoin условия:

 mapper( User, t_users, properties={ 'followers': relation( User, secondary=t_follows, primaryjoin=(t_follows.c.followee_id==t_users.c.id), secondaryjoin=(t_follows.c.follower_id==t_users.c.id), ), 'followees': relation( User, secondary=t_follows, primaryjoin=(t_follows.c.follower_id==t_users.c.id), secondaryjoin=(t_follows.c.followee_id==t_users.c.id), ), }, ) 

Я написал этот пример, чтобы помочь вам лучше понять, что primaryjoin параметры primaryjoin и secondaryjoin . Конечно, вы можете сделать его сортировщиком с backref .

BTW, вам не нужен столбец id в таблице ниже, вместо этого используйте составной первичный ключ. Фактически, вы должны определить уникальное ограничение follower_id и followee_id пары в любом случае (либо как основной, либо дополнительный уникальный ключ).

Вы также можете сделать это декларативно.

Вот аналогичный пример, основанный на вышеуказанном коде, я использую backref.

 VolumeRelationship = Table( 'VolumeRelationship', Base.metadata, Column('ParentID', Integer, ForeignKey('Volumes.ID')), Column('VolumeID', Integer, ForeignKey('Volumes.ID')) ) class Volume(Base): """ Volume Object """ __tablename__ = "Volumes" id = Column('ID', Integer, primary_key=True, nullable=False) type = Column('Type', String(25)) name = Column('Name', String(25)) poolid = Column('pool', Integer, ForeignKey('Pools.ID')) parents = relation( 'Volume',secondary=VolumeRelationship, primaryjoin=VolumeRelationship.c.VolumeID==id, secondaryjoin=VolumeRelationship.c.ParentID==id, backref="children") 
  • Как поместить метку SQLAlchemy в результат арифметического выражения?
  • pandas to_sql все столбцы как nvarchar
  • Связанные сравнения в SQLAlchemy
  • Помощь с копией и глубокой копией в Python
  • SQLAlchemy по умолчанию DateTime
  • экранирование специальных символов с использованием sqlalchemy
  • Sqlalchemy complex in_ статья
  • как я могу запросить данные, отфильтрованные столбцом JSON в SQLAlchemy?
  •  
    Interesting Posts for Van-Lav

    Неподдерживаемый флаг командной строки: -ignore-certificate-errors

    передача параметров в функцию обработчика apscheduler

    Удаление пунктуации из элементов списка Python

    Среднее количество деталей в списке списков

    Paramiko – Выполнение команд в "background"

    Загрузить файл в общедоступную папку на Google Диске – с помощью Python и без проверки подлинности?

    как проверить, соответствуют ли 3 символа в последовательном альфа-порядке

    Написание исходных данных на физический диск (флэш-накопитель) завершается неудачей с «Плохим дескриптором файла» в окнах – Python

    Render HTML в шаблоне django (не Unicode, а ASCII)

    Как определить, является ли строка escape-кодом unicode

    Почему перезагрузка записи с помощью update_one повысит значение ValueError?

    Как создать набор Python только с одним элементом?

    Класс Python, наследующий многопроцессорность, проблемы с доступом к членам класса

    Django Pandas для ответа HTTP (файл загрузки)

    Python Нажмите: После выполнения команды командой ПОСЛЕ команды

    Python - лучший язык программирования в мире.