Как создать отношение «многие ко многим» в SQLAlchemy (python, flask) для модели «Пользователь к себе»

Мне нужно создать таблицу с именем friends, она должна выглядеть так:

друзья:

  • Логин пользователя
  • id_друга

Я пытался сделать это с помощью учебных пособий из SQLALchemy, но я не нашел, как установить отношение «многие ко многим» для одной и той же таблицы.

Вот что я пробовал:

# friends table
# many to many - user - user
_friends = db.Table('friends',
    db.Column('user_id', db.Integer, db.ForeignKey('users.id')),
    db.Column('friend_id', db.Integer, db.ForeignKey('users.id'))
)


class User(db.Model, UserMixin):

    # table name in database
    __tablename__ = 'users'

    # primary key for table in db
    id = db.Column(db.Integer, primary_key=True)

    # email is unique!
    email = db.Column(db.String(255), unique=True)

    # password, max = 255
    password = db.Column(db.String(255))

    # category relation
    categories = relationship("Category")

    # cards relation
    cards = relationship("BusinessCard")

    # friends
    friends = db.relationship(
        'User',
        backref="users",
        secondary=_friends
    )

он говорит:

AmbiguousForeignKeysError: Не удалось определить условие соединения между родительскими и дочерними таблицами в отношении User.friends — существует несколько путей внешнего ключа, связывающих таблицы через «друзей» вторичной таблицы. Укажите аргумент «foreign_keys», предоставив список тех столбцов, которые следует учитывать как содержащие ссылку внешнего ключа из вторичной таблицы на каждую из родительских и дочерних таблиц.

кто-нибудь знает, как это сделать правильно?


person vromanch    schedule 17.01.2014    source источник


Ответы (3)


Шаблон, который вы пытаетесь реализовать, является частным случаем отношений «многие ко многим». SQLAlchemy называет это отношением списка смежности, и я рекомендую попробовать выполнить приведенный здесь код:

http://docs.sqlalchemy.org/en/rel_0_9/orm/relationships.html#adjacency-list-relationships

Ключом является kwarg 'remote_side'.

Вот почему: ошибка, которую вы получаете, связана с тем, что ваша таблица ассоциаций («друзья») имеет два внешних ключа, указывающих на таблицу «пользователи»: один в столбце «user_id» и один в столбце «friend_id». SQLAlchemy пытается автоматически определить отношения на основе внешних ключей, но это не удается, потому что он не может определить, в каком направлении идет отношение. Итак, если у вас есть запись в таблице «друзья», например

user_id   : 1
friend_id : 2

SQLAlchemy не может определить, есть ли у user_1 друг user_2 или наоборот.

Если это кажется запутанным, это так. Дружба в смысле социальных сетей может быть однозначной, и в этом случае user_1, имеющий друга user_2, не означает, что у user_2 есть друг user_1; или он может быть биективным, и в этом случае они эквивалентны. Здесь я показываю свой возраст, но первый представлен Livejournal, а второй — Facebook.

Я не знаю, как реализовать однозначное отношение в SQLAlchemy. Это уродливый UNION ALL или что-то в этом роде в MySQL.

person Channing Moore    schedule 17.01.2014

Учебник Мигеля Гринберга объясняет этот тип приложения.

http://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-viii-followers-contacts-and-friends

person Ang    schedule 17.01.2014

Вы не можете напрямую установить связь «многие ко многим» между двумя таблицами, вместо этого вам нужно использовать третью таблицу. введите здесь описание изображения

person user1587985    schedule 17.01.2014