Мне настраивали модель SQLAlchemy в моем приложении, которое должно подражать функциональности "подписчиков" на Twitter, т.е. пользователи имеют, имеют many-many отношения друг с другом (оба подписчика и после). Таблицы структурированы следующим образом (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?
В этом случае вам необходимо явно написать условия 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
и secondaryjoin
. Конечно, вы можете сделать его сортировщиком с помощью backref
.
Кстати, вам не нужен столбец id
в следующей таблице, используйте вместо него составной первичный ключ. Фактически, вы все равно должны определить уникальное ограничение пары follower_id
и followee_id
(как первичный или дополнительный уникальный ключ).